@getratchet/sdk
v0.2.6
Published
Durable tool execution, bounded API retries and workflow recovery with customer-owned TypeScript workers
Maintainers
Readme
GetRatchet TypeScript SDK
SDK documentation · Retry decisions · Idempotency guide
Durable, named and versioned tool execution for Node.js 22+. Supports ESM and CommonJS.
npm install @getratchet/sdkCreate separate INGEST and WORKER keys in GetRatchet Settings. Scope both to the same project/environment and allow echo@1 on the worker key. Keep keys in environment variables.
Producer:
import { createRatchet } from '@getratchet/sdk';
const ratchet = createRatchet({
baseUrl: 'https://getratchet.app',
apiKey: process.env.GETRATCHET_INGEST_KEY!,
});
await ratchet.startRun('First durable run', {
projectId: process.env.GETRATCHET_PROJECT_ID!,
environmentId: process.env.GETRATCHET_ENVIRONMENT_ID!,
});
await ratchet.enqueue({ message: 'hello' }, {
name: 'echo', version: '1', endpoint: 'Echo',
idempotencyKey: 'first-echo-1',
});
await ratchet.finishRun();Worker (a separate, long-running process):
import { createRatchet } from '@getratchet/sdk';
const worker = createRatchet({
baseUrl: 'https://getratchet.app',
apiKey: process.env.GETRATCHET_WORKER_KEY!,
});
worker.registerTool({
name: 'echo', version: '1',
handler: async (input: { message: string }) => ({ echo: input.message }),
});
process.once('SIGTERM', () => worker.worker.stop());
process.once('SIGINT', () => worker.worker.stop());
await worker.worker.start({ concurrency: 2 });GetRatchet stores and schedules work; your worker executes handlers. A run remains open until its pending work settles. Handlers may execute again after failure or an expired lease: pass context.idempotencyKey to the destination and use context.signal with downstream requests. This SDK does not guarantee exactly-once external side effects.
See the worker guide and repository for retries, dependencies, replay, contracts and optional telemetry.
License: MIT.
For interactive or CI operations without writing SDK code, see the ratchet CLI. It supports contract publication, synthetic tests, run inspection, guarded replay/cancellation and endpoint policies over the same API.
Durable retry policies and error decisions
Durable jobs support STANDARD (5 attempts, 30s initial, 15m cap), AGGRESSIVE (8 attempts, 5s initial, 5m cap), RELAXED (3 attempts, 120s initial, 30m cap), and CUSTOM. Built-ins double their delay with ±20% jitter; CUSTOM supplies maxAttempts, initialDelayMs, multiplier, maxDelayMs, and jitterPercent. Counts include the first execution. Caps precede jitter; the final safety limit is 24 hours.
A selected tool contract overrides the endpoint policy. Explicit enqueue maxAttempts overrides only the attempt count. Each new job snapshots the complete policy; later endpoint edits or contract publication do not change its policy or saved due time. Existing jobs without snapshot data keep the old preset behavior. Synthetic tests remain one attempt.
TypeScript handlers can throw RetryableError(message, { retryAfterMs }) or NonRetryableError(message) and register classifyError(error, context) for third-party failures. Python provides RetryableError(message, retry_after_ms=...), NonRetryableError, and classify_error. Unknown errors default to retryable; schema failures and cancellation remain non-retryable. A classifier failure is reported only to the local error callback and falls back to retryable.
Retry hints must be integer milliseconds from 1,000 to 86,400,000. The persisted delay is the greater of the normal jittered policy delay and the hint, capped at 24 hours; the hint itself is never jittered. An open circuit, pause, concurrency gate or attempt limit is never bypassed. Error objects, stacks and classifier metadata are not sent to the API.
Execution is at least once: a crash or lost report can repeat a completed side effect. Pass the stable job idempotency key to the destination and require destination-side deduplication for irreversible writes.
See custom policies and provider examples for endpoint/tool publication, validation limits, HTTP 429 with Retry-After, HTTP 503, non-retryable HTTP 400 validation failures, and unknown-error fallback.
Automatically generated idempotency keys
When omitted, the durable key hashes the run ID, tool name, handler version, selected contract version (or null), effective endpoint (defaults to the tool name), dependency step/status (or null), and input. Nested JSON object keys are sorted; array order is significant. Equivalent operations in one SDK therefore reuse a key regardless of object insertion order. TypeScript process-bound wrappers also include the effective endpoint. Explicit customer keys are never changed.
TypeScript and Python use the same operation fields and canonical JSON ordering, but native numeric serialization can differ between languages (for example Python 1.0 versus JavaScript 1). Use an explicit shared key when producers in different languages must deduplicate the same business operation. Generated keys changed in this release; carry forward explicit keys for operations queued by older SDKs. Selecting an implicit contract does not pin future publications: supply a contract version for a fixed operation identity.
See application monitoring and customer-owned Sentry opt-in for privacy, separate DSNs, release/source-map configuration, maintenance check-ins, verification and rollback. Customer SDKs do not initialize GetRatchet Sentry.
