SDK
Install @easel-sh/sdk and call the Easel API from Node.js, Bun, Deno, or edge runtimes.
@easel-sh/sdk is the TypeScript client for the Easel API. Each
method is a plain async function over fetch, so it runs in a route handler,
a queue worker, a CLI, or an edge function alike.
Install
The main entry runs on Node.js 20 or later, Bun, Deno, and edge runtimes; it
uses only fetch and Web Crypto. @easel-sh/sdk/node adds helpers that read
from disk, and needs Node.js.
Create a client
| Option | Description |
|---|---|
token | Required. A workspace or scoped token |
baseUrl | Defaults to https://app.easel.sh, or EASEL_API_URL when it's set |
maxAttempts | Attempts for rate-limited, 5xx, and network failures. Default 4 |
fetch | A custom fetch, for tests or runtimes without a global one |
userAgent | Sent as User-Agent. Defaults to easel-sdk/<version> |
Keep the client on your server. Never send the token to a browser or into a sandbox.
Retries and errors
The client retries 429 responses, and 5xx and network failures for reads
and for requests with an Idempotency-Key, with backoff. Every creating
method sends a new idempotency key unless you pass idempotencyKey, so a
retry never creates a second resource. Pass your own key, such as your
publish's ID, to make a whole publish safe to retry.
A non-2xx response throws EaselApiError:
EaselApiError has status, code, records, and the API's message. See
Errors for the codes.
Projects and environment variables
| Method | Description |
|---|---|
projects.ensure(name, settings?) | The project named name, created with settings if it doesn't exist. Safe on every publish |
projects.list(), get(project) | Read projects |
projects.create(input), update(project, changes), delete(project) | Manage a project |
env.upsert(project, vars) | Create variables, replacing any with the same key and branch |
env.list(project, { decrypt? }) | List variables, with values for non-sensitive ones when decrypt is true |
env.create, env.update, env.delete | Manage single variables |
project is a project's ID or slug everywhere.
Deploy
| Method | Description |
|---|---|
deployments.create({ project, target?, meta?, archive | files, prebuilt?, idempotencyKey? }) | Create a deployment; returns once it's queued |
deployments.createUpload({ project, target?, meta?, expiresIn? }) | A single-use upload URL for a sandbox |
deployments.getUpload(uploadId) | Whether an upload URL was used, and its deploymentId |
deployments.wait(id, { onStatus?, timeoutMs?, intervalMs? }) | Poll until the deployment reaches a final status |
deployments.get(id), list({ project, … }) | Read deployments |
deployments.logs(id), runtimeLogs(id, { since?, limit? }) | The build log, and the requests it served |
deployments.cancel(id) | Cancel a queued or building deployment |
deployments.promote({ project, deploymentId }) | Serve a deployment in production. Promoting a preview returns a new deployment with rebuilt: true |
deployments.rollback({ project, deploymentId }) | Serve an earlier production deployment again |
deployments.create() takes exactly one source:
archive: a gzip tarball, as bytes, aBlob, or aReadableStream, such astar czf -output. Sent in one request.files:[{ file, data, mode? }], withdataas a string or bytes. A set up to 2 MiB (INLINE_FILES_MAX_BYTES) goes inline in one request. Larger sets upload only the files Easel doesn't already have, then create the deployment.
wait() calls onStatus with the deployment each time its status changes,
and throws DeploymentWaitTimeoutError after timeoutMs, 10 minutes by
default.
sandboxUploadScript(uploadUrl, { cwd?, exclude? }) returns the shell
command that uploads a sandbox's working directory to an upload URL. See
Deploy source.
Domains, usage, webhooks, and tokens
| Method | Description |
|---|---|
domains.add(project, { name }), list, get, verify, remove | A project's domains |
wildcardDomains.add({ domain }), list, get, verify, remove | Your workspace's wildcard domains |
domainTarget.set(host), get, verify, remove | Your branded CNAME target |
usage.get({ from?, to?, projectId? }) | Usage per project |
webhooks.create({ url, events, projectIds? }), list, delete | Manage webhooks |
webhooks.verify(rawBody, headers, secret) | Check a delivery's signature and return its event |
tokens.create({ name, permissions, projectIds?, expiresIn }), list, revoke | Mint and revoke scoped tokens |
whoami() | The token's user and workspace |
request(method, path, options) | Call an endpoint the client doesn't wrap |
verifyWebhook() and signWebhook() are also exported on their own, for a
webhook receiver that doesn't create a client. See
Webhooks.
Deploy a folder from Node.js
@easel-sh/sdk/node deploys a directory on disk. It skips the same files as
easel deploy, including the patterns in the folder's .easelignore, packs
the rest into one tarball, and sends it:
collectDeployFiles() and createSourceArchiveTgz() are the two steps on
their own.
Types
Every request and response type is exported, such as Deployment,
ProjectDomain, WebhookEvent, and PermissionMap, along with the lists
WEBHOOK_EVENT_TYPES and PERMISSIONS.