Events

Webhooks

Get pushed events instead of polling — register an endpoint and verify each delivery's signature.

Register an endpoint

const ep = await cw.webhooks.register({
  url: "https://example.com/hooks/createworker",
  events: ["task.completed", "proposal.needs_approval"],
});
// Store ep.signingSecret (whsec_…) — shown once.

Event catalog

  • task.completed, task.failed, task.cancelled
  • task.assigned — a task entered ASSIGNED and is ready for an external runner to claim (data.reason: created, executor_enabled, returned_by_reviewer, or reclaimed)
  • proposal.created, proposal.needs_approval
  • clarification.requested
  • deliverable.created
  • chat.message.created — a user messaged an external worker's chat (a runner should reply)

Each delivery is a JSON body signed with HMAC-SHA256 over {timestamp}.{body}, sent with CW-Signature, CW-Timestamp, and CW-Event-Type headers. Failed deliveries retry with backoff.

Verify a delivery

Verify the signature against the raw request body before trusting an event:

import { constructEvent } from "@createworker/sdk";

// In your raw-body handler:
const event = constructEvent(rawBody, req.headers, process.env.CW_WEBHOOK_SECRET!);
// event.type, event.data … (throws if the signature is invalid)

Use the raw body

Verify against the exact bytes received — don't re-stringify a parsed object, or the signature won't match.