Durable Waits
A durable wait is a condition OtterKit holds for you on the server. Arm it on a live session ("when a request matching event.type = payment.succeeded lands") and disconnect: no polling loop, no open socket, no compute burning while you wait. When a matching request arrives, whether or not any client is attached, OtterKit POSTs it to your callback URL, signed, with retries. Agents park instead of waiting.
# When a matching Stripe event lands, call my CI back — then go do other work
npx otterkit wake hook-a1b2c3d4 \
--call https://ci.example.com/hooks/resume \
--field event.type=payment.succeeded
# Match on method and path prefix too (all clauses must hold)
npx otterkit wake hook-a1b2c3d4 --call https://... --method POST --path /stripeMatch clauses: --method (exact), --path (prefix), and --field (dot-path equality into a JSON body). Waits are one-shot, capped at 20 per session, and expire with the session (or sooner via --ttl). Manage them with otterkit waits list and otterkit waits cancel.
Verifying deliveries
Each wait gets a secret, shown once at creation. Deliveries carry X-OtterKit-Signature: sha256=<hmac>, the HMAC-SHA256 of the raw body with that secret, so your receiver can prove the callback came from OtterKit. Failed deliveries retry with backoff (1, 2, 4, 8 minutes; five attempts).
{
"waitId": "…",
"subdomain": "hook-a1b2c3d4",
"matchedAt": "2026-07-21T18:04:11.000Z",
"request": { "method": "POST", "path": "/stripe/webhooks", "headers": { "…": "…" }, "body": "<base64>" }
}Approval waits
An approval wait swaps the event source for a human. otterkit approve asks a question and blocks until someone taps Approve or Deny on the endpoint's page at app.otterkit.com/webhooks (or runs otterkit waits resolve). Deterministic exit codes make it a one-line gate in any script an agent runs.
npx otterkit approve hook-a1b2c3d4 "Deploy v2.1 to prod?" --timeout 1h \
&& ./deploy.sh \
|| echo "not approved"| Exit code | Meaning |
|---|---|
| 0 | Approved |
| 1 | Denied |
| 2 | No decision before --timeout |
Approvals resolve only through the session's connect token, never through the public URL, so a decision can't be forged by anyone who merely knows the endpoint address.
wait_create, wait_list, wait_cancel, and wait_resolve ship in otterkit mcp (CLI 0.13+), so an agent can arm a wait or request sign-off mid-task without shelling out.