Executable Webhooks
Webhooks let an external service invoke an active executable without a workspace API key. They are additive: the executable's cron or interval schedule continues to run.
Where webhooks are enabled, workspace owners and admins manage webhook URLs from Console → Executables → executable detail → Webhooks. Each executable can have up to ten active, named URLs.
Generate and protect the URL
Click Generate URL, give the caller a recognizable name, and copy the URL from the shown-once dialog. Thyme stores only a SHA-256 hash of its 256-bit secret, so the URL cannot be recovered later. If it is lost, rotate it. If it is exposed, revoke or rotate it immediately.
Rotating invalidates the old URL immediately and reveals a replacement once. Revocation is permanent and also blocks retained result links for that named webhook.
Invoke with predefined args
An empty POST, a whitespace-only body, or {} runs with the executable's predefined args.
curl --request POST "$THYME_WEBHOOK_URL" \
--header "Idempotency-Key: deploy-event-001"Invoke with custom args
A non-empty object completely replaces predefined args; values are never merged. It must fully satisfy the function's uploaded args schema.
curl --request POST "$THYME_WEBHOOK_URL" \
--header "Content-Type: application/json" \
--header "Idempotency-Key: rebalance-event-001" \
--data '{"recipient":"0x1111111111111111111111111111111111111111","amount":10}'The body limit is 256 KiB. Arrays, scalars, null, malformed JSON, missing required fields,
and wrong types are rejected before execution. A function without an args schema accepts only
the empty/predefined mode.
Idempotency and limits
Idempotency-Key is optional, 1–128 characters, and retained for 24 hours per named webhook.
Retrying the same request with the same key returns the original execution. Reusing the key
with different custom args returns 409 idempotency_conflict.
Use a key for any executable that may submit a transaction: without one, retrying after a network timeout can create a second execution.
Each named URL accepts at most 60 new executions per minute. A second request is rejected with
409 execution_in_progress while the executable already has an active execution or storage
lock.
Responses
Thyme waits up to 55 seconds for final post-processing. A fast execution returns 200 with:
- Execution status and ID
- Transaction and UserOperation hashes when submitted
- Gas, chain, timing, CU, and submitted-call metadata
- A 24-hour snapshot when the execution updated storage
- A sanitized semantic error for failed or skipped executions
Execution-level failed and skipped outcomes still use HTTP 200: the webhook was accepted
and delivered successfully, and data.status describes the task outcome. Validation,
authentication, rate, and availability errors use 4xx status codes.
If work is still running, the response is 202 Accepted with Location, Retry-After: 2,
and data.resultUrl. Poll that URL with GET. Send Prefer: respond-async to skip the initial
wait and receive 202 immediately.
A submitted_unknown outcome can remain unresolved after a receipt timeout; use the recorded hashes and authenticated monitoring to reconcile it before submitting another logical action. Results and updated-storage snapshots expire after 24 hours. Full sandbox logs are available through the authenticated Console and management API/CLI, not in webhook responses.
Common errors
| HTTP | Code | Meaning |
|---|---|---|
404 | not_found | URL is unknown, invalid, rotated, or revoked. |
409 | executable_unavailable | Executable/function is not active. |
409 | execution_in_progress | Another run currently owns the executable. |
409 | idempotency_conflict | Key was reused with a different request. |
413 | body_too_large | Body exceeds 256 KiB. |
415 | unsupported_media_type | Non-empty body is not JSON. |
422 | invalid_arguments | Custom args do not satisfy the schema. |
422 | arguments_schema_missing | Custom args were sent to a schema-less function. |
429 | rate_limited | Named webhook exceeded 60 new executions/minute. |