Sume TypeScript SDK quickstart: install, client, errors, retries
Install @sume-com/sdk, create one client with createSumeClient, and call typed operations that return errors instead of throwing, with retries built in.

The Sume TypeScript SDK is @sume-com/sdk, the official TypeScript client for api.sume.com: install it with npm install @sume-com/sdk, create one client with createSumeClient({ apiKey }), and pass that client to every call. It covers every operation in the public OpenAPI schema, adds helpers that wait for runs and jobs and verify webhooks, and retries transient failures by default.
Everything below comes from Sume's TypeScript SDK and Waiting for runs and jobs docs pages, read on 2026-09-26.
How do I install the Sume TypeScript SDK?
Run npm install @sume-com/sdk. The docs cite the published version 0.2.0, which is MIT licensed and has no runtime dependencies. It needs fetch and WebCrypto, and the docs name Node 18+, Bun, Deno, and Cloudflare Workers.
Use it on your server only: a Sume API key spends your credits and has no browser-safe variant, as How to embed AI video generation in your product explains.
How do I create a client?
Call createSumeClient once and thread the client through every call. Operations accept a module-level default client, but that default has no API key: it exists so the generated code compiles, not so you can skip the factory.
| Option | Default | Notes |
|---|---|---|
apiKey | None; required | A Developer API key from the API Keys dashboard. |
baseUrl | https://api.sume.com | The production API. |
fetch | The runtime's globalThis.fetch | A seam for instrumentation, retries, or tests. |
maxRetries | 2 retries | Retries 408, 429, 5xx, and transport failures. |
import { createSumeClient, listFormats } from "@sume-com/sdk";
const client = createSumeClient({ apiKey: process.env.SUME_API_KEY! });
const { data, error } = await listFormats({ client });
if (error) throw new Error(JSON.stringify(error));Which auth header does the SDK send?
The client sends x-api-key only and does not set Authorization. The API accepts either header alone but rejects both at once with 401 unauthorized and Send only one API key credential. Neither header wins, so a gateway credential or an interceptor that adds Authorization fails the request even though x-api-key was correct. If you pass your own fetch, make sure it does not add one.
Running Formats also needs a key with formats:read and formats:write, and a team Format needs a key created in that team's workspace; How Sume API keys work covers scopes and the 403 codes.
What are the generated operations?
Everything the package exports beyond the factory and its helpers is generated from the same OpenAPI schema as the API reference: one function per operation, named after the operation id, such as listFormats, createFormatRun, getFormatRunStatus, and cancelFormatRun. The docs send you to your editor's autocomplete for the full list. Exact request and response fields come from the API reference and the live OpenAPI at https://api.sume.com/reference/json, which stay the source of truth.
Generated operations do not throw on an API error. They resolve with { data, error, response }, so check error before reading data. The hand-written helpers on top include:
subscribeFormatRun: creates a Format run and waits for its terminal receipt.waitForRun: waits on a Format, Action, or Agent run id you already have.waitForJob: waits on a generation job at/v1/jobs/:id.verifyWebhook: checks thesume-v1signature on a webhook delivery.
How do typed errors work?
The wait helpers throw, because a poll loop has nowhere to put a non-result. The run helpers throw SumeRunRequestError when the create call was refused or a status read failed and was not transient, and SumeRunTimeoutError when timeout elapsed first; waitForJob throws its own SumeJobTimeoutError and SumeJobRequestError, both carrying jobId. SumeRunRequestError extends SumeApiError, so the error envelope arrives as typed fields: code, requestId, retryable, retryAfterSeconds, nextAction, details, and the raw body.
SumeApiError also has one subclass per status: SumeAuthenticationError (401), SumeInsufficientCreditsError (402), SumePermissionError (403), SumeNotFoundError (404), SumeConflictError (409), SumeRateLimitError (429), and SumeServerError (5xx). The run helpers always throw SumeRunRequestError itself, never one of these subclasses, so branch on its status or code.
import { SumeRunRequestError, subscribeFormatRun } from "@sume-com/sdk";
try {
const run = await subscribeFormatRun({ client, path, body });
} catch (error) {
if (
error instanceof SumeRunRequestError &&
(error.status === 402 || error.code === "insufficient_credits")
) {
return topUpAndAlert(error.requestId); // next_action: "add_funds"
}
if (error instanceof SumeRunRequestError) {
log.error({ code: error.code, requestId: error.requestId, retryable: error.retryable });
}
throw error;
}How does the SDK retry failed requests?
createSumeClient retries 408, 429, 5xx, and transport failures twice by default, with exponential backoff and jitter, and honors retry-after. The maxRetries and timeout options tune this layer.
- A
POSTis retried only when it carries anIdempotency-Key. Without one, a replay would start and bill a second run. subscribeFormatRungenerates a key for you unless you pass your own, ornullto send none.waitForRunalso tolerates six consecutive transient read failures (maxTransientFailures,onTransientError): a429or5xxon a status read means the read failed, not the run.- Timeouts, terminal statuses, and the job helper are covered in Wait for jobs and runs in the Sume SDK.
Sources
Related posts
Written by Sume