Skip to main content
EndstateClient takes a secret key (end_sk_...) and reaches every operation in the spec. It runs on your server only.
Never construct EndstateClient in browser or Electron-renderer code. A secret key grants full access to your organization. For the browser, see Browser.

Resources

Every operation is grouped by resource. Each method has its own reference page with the endpoint it calls, the credential it needs, and its retry class.

Waiting for work to finish

Issuance and provisioning are asynchronous. Rather than writing your own poll loop, use the waitUntil helpers - they share one polling primitive with exponential backoff, and they throw EndstateTerminalStateError when something settles in a failed state instead of polling until your budget runs out.
Each accepts { timeoutMs, intervalMs, maxIntervalMs, signal, onPoll }.

Pagination

A list call is both awaitable and iterable. Await it for one page, pagination envelope included; iterate it for items across every page, following nextCursor for you.
Cursors are opaque - pass nextCursor back unchanged and never parse one.

Issuing a session for a browser

A secret key may verify a tap on your server and hand the resulting session token to a page. Unlike a publishable key, it may also set ttl.
The page adopts it with endstate.session(token). See Tap sessions.

Environments

baseUrl is explicit and defaults to production. The SDK does not infer an environment from your credential’s prefix.
See Environments for what each one is for.

Anything a method does not cover

Every operation in the spec is reachable by id, typed to the credential you constructed the client with, so a new endpoint is usable before a convenience method exists for it.
The operation ids are the same ones in the API reference, and OPERATIONS exports the full table if you need to inspect it at runtime. request() and requestWithMeta() are wire-shaped in both directions: path, query, body, and response keys are the API’s own snake_case names, as components["schemas"] types them. The named resource methods above are the camelCase surface. The operation helpers on @endstate-sdk/core/types that type these calls (PathParams<Id>, QueryParams<Id>, RequestBody<Id>, ResponseBody<Id>) are wire-shaped too; annotate resource method inputs and results with the named types (Unit, CreateUnitRequest, …) instead. TypeScript checks for unknown keys only on object literals, so write the path, query and body here as literals or type them with components["schemas"]: a value typed with a camelCase SDK type such as CreateCollectionRequest compiles when it carries the required wire keys, is sent unconverted, and the API rejects the body with validation.failed or, for list filters, ignores the unknown keys and returns unfiltered results.