Getting started

Exports reference

Everything the package exports: the client, the factory, crypto helpers, constants, error classes and types.

@goenvless/sdk has a single entrypoint. Everything below is a named export from @goenvless/sdk.

Client

ExportSignature
init(options?: ClientOptions) => Envless
envlessEnvless, a live handle on whatever init installed
getClient() => Envless
resetClient() => void
createClient(options?: ClientOptions) => Envless
Envlessnew (options: TransportOptions) => Envless, also the default export

init and createClient read ENVLESS_TOKEN and ENVLESS_API_ENDPOINT when process exists. new Envless() reads no environment. See Create a client.

ts
import { envless, init } from '@goenvless/sdk'

init({ token: process.env.ENVLESS_TOKEN })

await envless.products.list()

Crypto

ExportSignature
encryptValue(plaintext: string, passphrase: string, workspaceId: string) => Promise<string>
decryptValue(ciphertext: string, passphrase: string, workspaceId: string) => Promise<string>
encryptWithKey(key: CryptoKey, plaintext: string) => Promise<string>
decryptWithKey(key: CryptoKey, ciphertext: string) => Promise<string>
deriveWorkspaceKey(passphrase: string, workspaceId: string) => Promise<CryptoKey>
importWorkspaceKey(base64url: string) => Promise<CryptoKey>
isCiphertext(value: unknown) => boolean
passphraseStrength(passphrase: string) => PassphraseValidation
ENCRYPTION_PARAMETERSThe exact cryptographic constants

See Encryption for the recipe and for why you should derive the key once when writing a batch.

Helpers

ExportSignature
rotateWorkspacePassphrase(props: RotatePassphraseProps) => Promise<RotatePassphraseResult>
verifyWebhookSignature<T>(props: VerifyWebhookProps) => Promise<WebhookEvent<T>>

rotateWorkspacePassphrase re-encrypts live variables and version history for one environment, which is the part that is easy to forget. verifyWebhookSignature is the receiver side of Webhooks.

Errors

ExportNotes
EnvlessApiErrorThe API answered with a failure. Carries status, code, resource, field, requestId, retryAfterSeconds.
EnvlessNetworkErrorNothing came back: connection failure, timeout, abort.

See Errors.

Constants

Enum-like values, so you never hard-code a string the API might reject.

ExportContents
SCOPE_RESOURCESworkspace, products, product-access, projects, environments, variables, versions, members, roles, keys, webhooks
SCOPE_LEVELSnone, read, write
VARIABLE_TYPEstring, number, boolean
VARIABLE_VISIBILITY_LEVELSserver, client
WEBHOOK_SIGNATURE_HEADERSwebhook-id, webhook-timestamp, webhook-signature, Envless-Event, Envless-Delivery
PAGE_LIMITSMAX_LIMIT: 100, DEFAULT_LIMIT: 25
ts
import { SCOPE_LEVELS, SCOPE_RESOURCES, VARIABLE_VISIBILITY_LEVELS } from '@goenvless/sdk'

await envless.keys.create({
    name: 'ci',
    scopes: {
        [SCOPE_RESOURCES.VARIABLES]: SCOPE_LEVELS.READ,
        [SCOPE_RESOURCES.VERSIONS]: SCOPE_LEVELS.READ
    }
})

await envless.variables.create('web', 'production', {
    name: 'NEXT_PUBLIC_API_URL',
    value: ciphertext,
    visibility: VARIABLE_VISIBILITY_LEVELS.CLIENT
})

Types

Every request body, option bag and response is an exported type. Import them with import type.

Client and transport

ClientOptions, TransportOptions, RequestOptions, RequestScope, ProductScope, ListOptions, DeliveryListOptions, Page, PaginationEnvelope, ApiEnvelope

Resources

IdentityResource, UserSummary, RoleSummary, WorkspaceResource, CurrentWorkspaceResource, UpdatedWorkspaceResource, DeletedWorkspaceResource, CustomDomainResource, CustomDomainRecord, RemovedDomainResource, ProductResource, DeletedProductResource, ProductAccessEntry, ProductAccessPage, GrantedProductAccessResource, RevokedProductAccessResource, ProjectResource, DeletedProjectResource, EnvironmentResource, EnvironmentSummaryResource, DeletedEnvironmentResource, VariableResource, DeletedVariableResource, DeletedVariablesResource, CreatedVariablesResource, VariableHistoryEvent, VersionResource, VersionDetailResource, VersionEntryResource, RolledBackVersionResource, ReencryptedEntriesResource, MemberResource, DeletedMemberResource, LeftWorkspaceResource, InviteResource, RevokedInviteResource, RoleResource, DeletedRoleResource, PermissionResource, PermissionsResource, KeyResource, CreatedKeyResource, DeletedKeyResource, WebhookResource, CreatedWebhookResource, DeletedWebhookResource, RotatedSecretResource, WebhookDeliveryResource, WebhookDeliveryDetailResource, RedeliveredWebhookResource, EventTypesResource

Inputs

WorkspaceCreate, WorkspacePatch, DomainVerifyOptions, ProductCreate, ProductPatch, ProjectCreate, ProjectPatch, EnvironmentCreate, EnvironmentPatch, VariableInput, VariablePatch, VersionCreate, MemberInvite, MemberPatch, RoleCreate, RolePatch, KeyCreate, KeyPatch, WebhookCreate, WebhookPatch, ApplyChanges, ApplyBaselineEntry, ApplyUpdateEntry, ApplyResult, ReencryptEntryInput

Crypto and webhooks

EncryptionParameters, PassphraseValidation, RotatePassphraseProps, RotatePassphraseResult, RotatePassphraseIssue, VerifyWebhookProps, WebhookSignatureHeaders, WebhookEvent

Read shapes are not always the write shapes. workspace.get resolves CurrentWorkspaceResource, with createdAt but no virtualEnvsEnabled, while workspace.update resolves UpdatedWorkspaceResource, with virtualEnvsEnabled but no createdAt. The method pages call these out individually.

A worked example

ts
import {
    encryptValue,
    envless,
    init,
    SCOPE_LEVELS,
    SCOPE_RESOURCES
} from '@goenvless/sdk'

init({ token: process.env.ENVLESS_TOKEN })

const { workspaceId } = await envless.me.get()

const product = await envless.products.create({ name: 'Internal tools', slug: 'internal-tools' })
const project = await envless.projects.create({ name: 'API', slug: 'api', product: product.slug })

for (const name of ['development', 'staging', 'production']) {
    await envless.environments.create(project.slug, { name, slug: name }, { product: product.slug })
}

await envless.variables.createMany('api', 'production', [
    { name: 'DATABASE_URL', value: await encryptValue(databaseUrl, passphrase, workspaceId) },
    { name: 'PORT', value: await encryptValue('3000', passphrase, workspaceId), type: 'number' }
], { product: product.slug })

await envless.versions.create('api', 'production', { note: 'Initial provisioning' }, { product: product.slug })

const key = await envless.keys.create({
    name: 'api-runner',
    scopes: { [SCOPE_RESOURCES.VARIABLES]: SCOPE_LEVELS.READ },
    projectIds: [project.id]
})

console.log(key.secret)