@createworker/sdk
v1.4.0
Published
Official TypeScript/Node SDK for the CreateWorker API — create and run AI agents, read results, approve actions, verify webhooks.
Maintainers
Readme
@createworker/sdk
Official TypeScript/Node SDK for the CreateWorker API. Create and run AI agents ("workers"), read results, approve actions, and verify webhooks.
Requires Node 18+ (uses the built-in
fetchandcrypto). Zero runtime dependencies.
Install
npm install @createworker/sdkQuick start
import { CreateWorker } from "@createworker/sdk";
const cw = new CreateWorker({ apiKey: process.env.CREATEWORKER_API_KEY! });
// Create a task for a worker (async — returns 202 immediately)
const task = await cw.tasks.create({
workerId: "wrk_…",
title: "Summarize this week's support tickets",
payload: { since: "2026-06-22" },
});
// Wait until it needs approval or finishes
const done = await cw.tasks.waitForTask(task.id, { timeoutMs: 120_000 });
if (done.status === "PROPOSED") {
await cw.approvals.create(task.id, { decision: "APPROVE" });
}
// Read deliverables
const { data: deliverables } = await cw.tasks.deliverables(task.id);
console.log(deliverables[0]?.content);Configuration
new CreateWorker({
apiKey: "cw_live_…", // required
baseUrl: "https://app.createworker.ai", // your deployment host (default)
timeoutMs: 30_000, // per-request timeout
maxRetries: 2, // retries on 429/5xx, honoring Retry-After
});Errors throw CreateWorkerError with .status, .code, and .referenceId.
Resources
account.get()·account.usage()workers.list() / get() / create() / update() / delete()—create/updateacceptexternalExecutortasks.list() / get() / create() / cancel() / deliverables() / waitForTask()tasks.claim() / progress() / submitDeliverable()— external-worker runner (see below)chat.pending() / messages() / reply()— answer an external worker's chatapprovals.create()·clarifications.answer()deliverables.get()knowledge.list() / get() / create() / delete()integrations.connections() / bindings() / bind() / unbind()webhooks.list() / get() / register() / update() / delete()
POST helpers send an auto-generated Idempotency-Key so retries are safe (pass your own to tasks.create(body, key)).
Webhooks
Register an endpoint and verify deliveries:
const ep = await cw.webhooks.register({
url: "https://example.com/hooks/createworker",
events: ["task.completed", "proposal.needs_approval", "chat.message.created"],
});
// Store ep.signingSecret (shown only once).import { constructEvent } from "@createworker/sdk";
// In your raw-body webhook handler:
const event = constructEvent(rawBody, req.headers, process.env.CW_WEBHOOK_SECRET!);
// event.type, event.data… (throws if the signature is invalid)Connect your own app
Let a worker operate your app's API (outbound), and/or let your app trigger workers (inbound).
Outbound — a worker manages your site:
const conn = await cw.integrations.createApiConnection({
displayName: "My portfolio",
baseUrl: "https://api.myportfolio.com",
allowedHosts: ["api.myportfolio.com"], // SSRF allowlist (required)
authMode: "bearer",
bearerToken: process.env.MY_PORTFOLIO_TOKEN!,
});
await cw.integrations.bind({ workerId, connectionId: conn.id, purpose: "OUTBOUND" });
// Optional: upload your API reference so the worker knows the endpoints.
await cw.knowledge.create({ title: "Portfolio API", content: "POST /projects { title, body } …" });
// Now tasks can act on your site (writes stay approval-gated unless the worker is AUTO_EXECUTE):
await cw.tasks.create({ workerId, title: "Publish a new project: 'Aurora' …" });Inbound — your app triggers a worker:
const wh = await cw.integrations.createWebhookConnection({
displayName: "Helpdesk",
inbound: { authMode: "signature", generateSecret: true },
});
await cw.integrations.bind({ workerId, connectionId: wh.id, purpose: "INBOUND" });
// Store wh.inbound.endpointUrl and wh.signingSecret (shown once).Then, from your app, POST a signed event — it becomes a task for the bound worker:
import { signInboundRequest } from "@createworker/sdk";
const { body, headers } = signInboundRequest(
{ externalId: "ticket-123", type: "ticket.created", task: { title: "New ticket #123", description: "…" } },
process.env.CW_INBOUND_SECRET!, // = wh.signingSecret
);
await fetch(endpointUrl, { method: "POST", headers, body });External workers (bring your own agent)
Mark a worker as external (externalExecutor: true) and its tasks are held for your AI agent (e.g. Claude Code) to run, instead of CreateWorker's models. Your runner polls, claims, works, and submits a deliverable you approve; it can also answer the worker's chat.
// Runner loop: claim assigned work, do it, submit the result.
const { data: tasks } = await cw.tasks.list({ status: "ASSIGNED", workerId });
for (const t of tasks) {
await cw.tasks.claim(t.id); // → IN_PROGRESS (409 if another runner has it)
await cw.tasks.progress(t.id, { note: "picked up" }); // optional; state: "blocked" pauses it
// …do the work…
await cw.tasks.submitDeliverable(t.id, { // → IN_REVIEW for a human to approve
title: "Done", summary: "…", content: "# result…",
links: [{ label: "PR", url: "https://github.com/…/pull/1" }],
});
}
// Answer the worker's dashboard chat:
const { data: turns } = await cw.chat.pending({ workerId });
for (const turn of turns) {
await cw.chat.reply(turn.sessionId, { content: "Here's what I found…" });
}Needs a key with tasks:read, tasks:write, deliverables:write, and (for chat) chat:read, chat:write. Full guide: /docs/api-sdk/external-workers.
API reference
Interactive docs: https://<your-host>/api/v1/docs · OpenAPI: /api/v1/openapi.json.
Versioning
SemVer; the SDK major tracks the API version (1.x ↔ API v1).
License
MIT
