Skip to main content
This reference describes @erstan/sdk@0.1.0-beta.1, a JavaScript ESM package with TypeScript declarations for Node.js 22+. See the quickstart for current private-beta availability and installation.

Client configuration

Every method accepts request options as its last argument: signal, timeoutMs, and maxRetries. Waiting methods also accept waitTimeoutMs (default 300,000 ms) and pollIntervalMs (default 1,000 ms). The wait deadline starts after launch or continuation acceptance, or on entry to wait; it does not include submission. traceEvents additionally accepts maxPages (default 1,000). Convenience run/wait operations pin one credential for the sequence. Separate calls use the provider’s current key. Erstan restricts run access to the exact key that created the run, so replacing a key is not a recovery path for old runs.

Published Agents and runs

All methods below are on client. Optional request options are omitted from the table unless needed to distinguish a signature. Run bodies contain input, optional laneId, attachments, and idempotencyKey. Select the Agent and lane intentionally; do not pick the first available Agent automatically. Attachments use { name, type, base64 } or { name, type, storageKey }, subject to the lane policy and 25 MB request limit. The SDK does not read local file paths or upload files implicitly. Runtime control fields such as Skill selections do not belong in business input. Continuation bodies include message and may include an idempotencyKey. Always follow the returned run ID. See Run Agents for continuation and lane constraints.

Waiting and human interactions

RunWaitResult.reason is completed, failed, cancelled, interaction, waiting, or unknown_status. The result includes run; finalResponse is typed as unknown. Failed Agent execution is a result, not an HTTP exception. Only an actionable pending interaction can be answered. reply uses the current interactionId plus message or structured answers; decideApproval uses { interactionId, action: 'approve' | 'reject' }. Retained/resuming interrupts and asynchronous batches keep polling. Other pauses and unknown future statuses return control. Nothing auto-approves or answers for the user. Aborting a request or timing out observation does not cancel remote work. Persist accepted run IDs and resume with runs.wait. Cancellation is a separate intentional call and cannot undo external effects that already occurred.

Durable trace paging

Trace queries accept cursor, limit, eventTypes, includePayloads, and payloadMaxChars. Payloads are opt-in and remain potentially sensitive even after server redaction. Sequence values stay strings.
This is durable event retrieval, not a live token stream or an indefinite tail. The iterator stops at the last available page, preserves filters, and rejects repeated cursors. Reaching its page limit raises a protocol error; use trace with an explicit cursor for manual paging. Breaking iteration does not cancel the run.

Agent and Skill authoring

context.get() returns workspaceId, actor, scopes, available teams, and capabilities. Check the expected workspace before making changes. The beta SDK requires stagedAuthoring: true and authoringContract: '2026-09-09.1' for authoring. Preview additionally requires guardedPreviews; explicit Skill selections also require draftSkillOverrides. An older or disabled server raises ErstanCapabilityError before the authoring call. Published runtime methods do not depend on staged-authoring support. agents.list/get are authoring reads, not aliases for listPublished/getPublished. Authoring list queries accept cursor, limit, and query. Pass nextCursor unchanged for the next page; do not invent offset pagination. Catalog queries and node fields follow the included TypeScript declarations and live guide. Catalog discovery is currently unavailable to team-restricted keys; do not broaden a key automatically to work around that restriction. Agent creation requires a target teamId, name, and complete nodes and edges. Updates replace supplied node/edge arrays in full; preserve unrelated content and unknown graph fields. Agent validation accepts proposed content or an agentId. Skill creation and updates use a complete packageJson; create also requires name. Skill validation accepts { packageJson, ... }. Preserve every related file, action declaration, and extension field. Full offline JSON/ZIP codecs are in the separate @erstan/skill-package package.

Permissions and lifecycle

These are additive to current workspace/team permissions and server capabilities. A key that can validate through REST also has authoring write authority; it is not a validation-only credential for untrusted PR code. Saving stages Skill content while the previous published package remains live. Agent name, description, category, tags, difficulty, and estimated time stage with the graph and promote together; behavior type stays immutable after first publication. Validation, preview, and publication are independent operations. Publishing does not require a successful test receipt or a particular workflow. Publish required Skills explicitly before the Agent. Agent publication never publishes dependencies for you. Publishing a shared Skill affects future consumers, while snapshot-backed admitted runs and their continuations retain their selected packages. Legacy runs without snapshot evidence cannot be assumed to have that guarantee. Multiple resource writes are not an atomic deployment.

Guards, idempotency, and preview

writeOptions requires { idempotencyKey }. guardedOptions requires both { revision, idempotencyKey }; the SDK sends the revision as If-Match. Keep content and its returned revision together. Historical version reads are read-only. After a 412 conflict, re-read and reconcile rather than replacing the guard on stale local edits.
Preview bodies contain input, optional laneId, and optional top-level skillVersions: [{ skillId, version }]. Each selected Skill requires edit permission and must fit the Agent’s existing Skill policy. Unselected Skills and child Agents retain published content. Preview never runs unsaved local files, auto-publishes dependencies, or bypasses approvals. It seals the selected graph; later edits or publication can fork and advance the version. Preview can incur costs and external effects, so invoke it only deliberately. For identical authoring intent, same-key response recovery is available for 24 hours; retained tombstones prevent duplicate dispatch afterward. This is at-most-once dispatch, not multi-resource atomicity. A lost response, authoring_outcome_unknown, or expired receipt requires reconciliation before any new mutation. Never blindly generate a fresh key to repeat an uncertain write, or reuse a key with changed content or guards.

Errors and retry behavior

ErstanError is the base error. ErstanAPIError exposes status, code, details, requestId, eventId, and retryAfterMs when available. Subclasses distinguish authentication, permission, not-found, validation, conflict, capability, and rate-limit errors. Configuration, connection, timeout, abort, and protocol errors also have distinct classes. ErstanWaitTimeoutError includes runId and the last observed run when available; other observation errors may also carry them. See API errors for server codes. Safe reads retry transient network errors and HTTP 408/429/500/502/503/504. Run starts and continuations retry only with a non-empty body idempotencyKey. Cancellation is idempotent. Replies and approval decisions never retry automatically; inspect the current interaction after uncertainty. Authoring mutations use their explicit keys and guarded receipt contract. Authorization, validation, and conflict errors are not resolved by automatic retry.

Advanced MCP access

listTools(query?, options?), callTool(name, args?, options?), and request(method, params?, options?) target Erstan’s stateless JSON-response /v1/mcp endpoint using the same API-key configuration. This is not a generic MCP transport or OAuth client: SSE, sessions, and notifications are unsupported. Tool calls are not automatically retried, and isError remains part of the result. JSON-RPC failures raise ErstanMcpError from the MCP subpath. Use the live tool schema: MCP Skill updates/publication use expectedVersion, not REST revision headers, and MCP Skill mutations have no idempotency argument. REST/SDK history and cancellation methods do not imply equivalent MCP tools. For host-managed OAuth, use the plugin.