webhooks
Webhook subscription management, delivery inspection, and retries
limai webhooks <subcommand>Manage project webhook subscriptions: create and configure them, verify the endpoint, pause and resume delivery, rotate the signing secret, inspect deliveries and metrics, and retry failed deliveries.
--jsonOutput raw JSON--verboseEnable debug loggingEvery subcommand takes the project ID first, then the webhook ID -- the same shape as limai agents get <projectId> <agentId>.
They all wrap the Webhook Management API and need a token whose role is OWNER or DEVELOPER -- reads included. For the event payloads your endpoint receives, see Webhook Setup.
Subcommands
limai webhooks list <projectId>
List every webhook subscription in a project, newest first.
limai webhooks list <projectId>limai webhooks get <projectId> <webhookId>
Show one subscription: URL, events, active and verified state, and its routes.
limai webhooks get <projectId> <webhookId>The signing secret is never shown here. It is printed only by create and rotate-secret.
limai webhooks create <projectId>
Create a subscription and print its signing secret. No later command reads the secret back -- store it before moving on. The only other way to see one is rotate-secret, which replaces it with a new one.
limai webhooks create <projectId>Create a webhook subscription.
--url <url>HTTPS endpoint to deliver to--event <eventType>Event type to subscribe to (repeatable)--deployment-id <id>Deployment route (repeatable, max 100)--agent-id <id>Agent route (repeatable, max 100)--classifier-id <id>Classifier route (repeatable, max 100)--splitter-id <id>Splitter route (repeatable, max 100)Every flag is optional, --url included. A subscription created with a URL, at least one event and at least one route comes back active; anything less comes back as an inactive draft you can fill in over several update calls. Either way it starts unverified, and nothing is delivered until verify succeeds.
A subscription needs a route of every family it subscribes to: a deployment route for document events, a classifier route for classification events, a splitter route for split events, an agent route for agent events. Mixing families in one subscription is fine as long as each has its routes. See Routing Families.
limai webhooks update <projectId> <webhookId>
Change a subscription. Only the flags you pass are applied; at least one is required.
limai webhooks update <projectId> <webhookId>Update a webhook subscription.
--url <url>New HTTPS endpoint; clears the verified state--event <eventType>Replaces the subscribed event types (repeatable)--deployment-id <id>Replaces the deployment routes (repeatable)--agent-id <id>Replaces the agent routes (repeatable)--classifier-id <id>Replaces the classifier routes (repeatable)--splitter-id <id>Replaces the splitter routes (repeatable)--activeEnable delivery--inactiveDisable deliveryRoute flags replace their family rather than adding to it: passing --deployment-id dep_1 on a subscription already routed to dep_1 and dep_2 leaves only dep_1. Families you do not mention are left alone.
Changing --url resets the verified state, so run verify again afterwards or delivery stays stopped.
limai webhooks delete <projectId> <webhookId>
Delete a subscription and its routes. Not reversible -- use pause to stop delivery without losing the configuration.
limai webhooks delete <projectId> <webhookId>limai webhooks pause <projectId> <webhookId>
Stop delivery, keeping the URL, events, routes, secret and verified state.
limai webhooks pause <projectId> <webhookId>limai webhooks resume <projectId> <webhookId>
Re-enable delivery. Only takes effect if the subscription is also verified.
limai webhooks resume <projectId> <webhookId>limai webhooks verify <projectId> <webhookId>
Send a signed VERIFICATION challenge to the subscription's URL. Your endpoint must echo the challenge value back in its response body. On success the subscription becomes verified and deliveries start flowing.
limai webhooks verify <projectId> <webhookId>Verification pings are never written to the delivery log, so a successful verify will not show up in deliveries.
limai webhooks rotate-secret <projectId> <webhookId>
Generate a new signing secret and print it. Every event enqueued after the rotation is signed with the new secret.
limai webhooks rotate-secret <projectId> <webhookId>Rotation does not reach into the delivery queue. A job captures the URL and secret when it is enqueued, and keeps them: deliveries that were already queued or mid-retry when you rotated are still signed with the old secret, and so is any manual retry of a delivery that was enqueued before the rotation. Automatic retries drain within a few minutes (five attempts, 10 s exponential backoff), but the retained payload can be retried by hand for about 7 days -- keep accepting the old secret for as long as you may retry such deliveries.
Rotation also clears the verified state -- run verify again once your endpoint knows the new secret.
limai webhooks deliveries <projectId> <webhookId>
Inspect the delivery log for a subscription, newest first.
limai webhooks deliveries <projectId> <webhookId>List webhook deliveries.
--status <status>Filter by status: success, failed, dead_lettered, retrying, pending--event-type <eventType>Filter by event type--deployment-id <id>Only deliveries routed by this deployment--agent-id <id>Only deliveries routed by this agent--classifier-id <id>Only deliveries routed by this classifier--splitter-id <id>Only deliveries routed by this splitter--limit <n>Page size, 1 to 200(default: 50)--offset <n>Rows to skip(default: 0)Use one route filter at a time.
An empty log does not prove nothing was delivered: delivery recording only began on 2026-08-26, and events enqueued before that were never written down. See What the Delivery Log Does Not Tell You.
limai webhooks metrics <projectId> <webhookId>
Aggregated delivery counts over a time window, broken down per route and bucketed into a series.
limai webhooks metrics <projectId> <webhookId>Show webhook delivery metrics.
--window <window>Time window: 24h, 7d or 30d(default: 30d)--bucket <bucket>Series granularity: hour or day. Defaults to hour for 24h, day otherwiselimai webhooks retry <projectId> <webhookId>
Re-queue deliveries that ended failed or dead_lettered. A retry replays the job exactly as it was enqueued -- the URL and secret captured at enqueue time, not the subscription's current ones. To re-send to a new URL or with a new secret, re-drive the event from your own side.
limai webhooks retry <projectId> <webhookId>Retry failed webhook deliveries.
--event-id <eventId>Event ID to retry (repeatable, 1 to 100 per call)The command reports what it re-queued and what it skipped. A skipped delivery carries a reason: already_delivered (the queued job succeeded), in_flight (an attempt is already scheduled or running), or payload_unavailable (the retained payload is gone).
Retry reaches back about 7 days for both failed and dead-lettered deliveries, and only the most recent few thousand of each are retained -- a busy project loses reach sooner. Past that, the delivery still appears in deliveries but comes back payload_unavailable; re-drive it from your own side instead.
Examples
Create a webhook for a deployment, then verify it
limai webhooks create proj_abc123 \
--url https://example.com/hooks/limai \
--event DOCUMENT_EXTRACTED \
--event DOCUMENT_EXTRACTION_FAILED \
--deployment-id dep_123abcStore the secretKey it prints -- your endpoint needs it to check the X-Webhook-Signature header, and no later command will show it again.
limai webhooks verify proj_abc123 whk_abc123The subscription is now active and verified, and events start arriving.
Inspect deliveries and retry a failed one
limai webhooks deliveries proj_abc123 whk_abc123 --status failedlimai webhooks retry proj_abc123 whk_abc123 \
--event-id evt_1756199524000_k3f9x2mq7abWatch a subscription's health
limai webhooks metrics proj_abc123 whk_abc123 --window 24hStart from a draft and fill it in
limai webhooks create proj_abc123
limai webhooks update proj_abc123 whk_abc123 \
--url https://example.com/hooks/limai \
--event DOCUMENT_EXTRACTED \
--deployment-id dep_123abc \
--active
limai webhooks verify proj_abc123 whk_abc123A subscription created with no flags is an inactive, unverified draft, and nothing switches it on for you: update only changes the fields you pass, and verify only sets the verified state. Pass --active on the update (or run resume afterwards) once it has a URL, an event and a route, then verify -- delivery starts only when it is both active and verified.
Add a classifier route to an existing subscription
limai webhooks update proj_abc123 whk_abc123 \
--event DOCUMENT_EXTRACTED \
--event DOCUMENT_CLASSIFIED \
--classifier-id cls_456defThe existing deployment routes are left alone because --deployment-id is not passed -- passing it would replace that family with whatever you list. What does have to be repeated is the full event list: --event replaces the subscribed events, so leaving out DOCUMENT_EXTRACTED would unsubscribe it. Classification events need a classifier route of their own, which is what --classifier-id adds.
Pause delivery while your endpoint is down
limai webhooks pause proj_abc123 whk_abc123
limai webhooks resume proj_abc123 whk_abc123Pausing does not clear the verified state, so resuming needs no re-verification.
Rotate the signing secret
limai webhooks rotate-secret proj_abc123 whk_abc123
limai webhooks verify proj_abc123 whk_abc123Deploy the new secret to your endpoint between the two commands.
Script against the JSON output
limai webhooks deliveries proj_abc123 whk_abc123 --status failed --json \
| jq -r '.deliveries[].eventId'