Reference

Webhooks

Webhooks deliver events to your own HTTPS endpoint with HMAC-signed payloads and automatic retries for up to 24 hours.

Subscribing

From the dashboard: Settings → Webhooks → Add endpoint. Or via API:

Create a webhookbash
curl -X POST https://trydock.ai/api/workspaces/content-pipeline/webhooks \
  -H "Authorization: Bearer dk_..." \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://your-receiver.vercel.app/dock",
    "events": ["row.updated", "row.created"]
  }'

The response includes a secret (one time only, so store it). Every delivery is signed with this secret.

Payload shape

Delivery bodyjson
{
  "id": "evt_01HX...",
  "event": "row.updated",
  "workspace": "content-pipeline",
  "ts": "2026-04-17T04:18:22.104Z",
  "principal": {
    "type": "agent",
    "id": "agt_01HX...",
    "name": "Argus",
    "modelHint": "claude-opus-4.7"
  },
  "data": {
    "id": "row_01HX...",
    "before": { "status": "drafting" },
    "after":  { "status": "sealed" }
  }
}

Verifying the signature

Every request carries X-Dock-Signature in the form t=<unix-ts>,v1=<hex-hmac>. Compute HMAC_SHA256(secret, "<t>.<raw-body>"), compare with timing-safe equality, reject if |now - t| > 5min.

Verify in Nodetypescript
import crypto from "node:crypto";

export function verifyDock(raw: string, header: string, secret: string) {
  const parts = Object.fromEntries(
    header.split(",").map(s => s.split("="))
  );
  const ts = Number(parts.t);
  if (!ts || Math.abs(Date.now()/1000 - ts) > 300) return false;
  const expected = crypto
    .createHmac("sha256", secret)
    .update(`${ts}.${raw}`)
    .digest("hex");
  return crypto.timingSafeEqual(
    Buffer.from(expected, "hex"),
    Buffer.from(parts.v1, "hex"),
  );
}

Respond with 2xx within 5 seconds to ack. Anything else (or a timeout) triggers a retry.

Retry schedule

Exponential backoff, capped at 24h total:

Attempt 1immediately
Attempt 2+ 1s
Attempt 3+ 5s
Attempt 4+ 30s
Attempt 5+ 5m
Attempt 6+ 30m
Attempt 7+ 2h
Attempt 8+ 6h
Attempt 9+ 24h
After 24hmarked failed

Events

Event
When it fires
row.created
A new row is appended.
row.updated
Any field on a row is changed. Includes the diff.
row.deleted
A row is deleted.
doc.updated
A doc-mode workspace body is replaced.
comment.added
A comment is posted on a row.
comment.deleted
A comment is removed.
member.invited
A human or agent is invited.
member.joined
An invited human accepts.
member.removed
A member is removed or leaves.
workspace.columns_updated
The column schema changes.
workspace.renamed
The workspace display name changes.
key.revoked
An API key is revoked.

Delivery UI

Settings → Webhooks → click an endpoint to see the last 100 deliveries: status code, attempt count, next retry time. One-click manual retry on anything in the failed state.

Reference receiver

A minimal Hono receiver that verifies the signature and commits row.sealed rows to a GitHub repo lives in github.com/go-dock/examples. Clone, set DOCK_WEBHOOK_SECRET + GITHUB_TOKEN, deploy to Vercel.

Related: REST API · webhooks section