Start a workflow from an inbound webhook
Choose An inbound webhook is received when editing a workflow. Save it, then create the hook in its trigger panel. Hook management requires both CRM edit and integration management permission. Agent credentials cannot create or rotate hooks; a human-custody standard organization write key may do so through QAC/MCP.
Choose a signed request (HMAC) or secret token. Copy the secret when it is created: it cannot be retrieved later. Rotating keeps the URL and delivery history but immediately invalidates the previous secret. Disable stops receipt. The URL is unique to this workflow.
Signed requests use X-GoodQA-Signature: t=<unix-seconds>,v1=<hex> where the signature is HMAC-SHA256(secret, timestamp + "." + exact JSON body). Timestamps must be within 300 seconds of the server clock. Token requests use X-GoodQA-Hook-Token and must supply X-GoodQA-Delivery. Delivery IDs contain 8–128 printable ASCII characters. Supplying a delivery ID with signed requests is recommended; otherwise the timestamp and body determine it.
The body must be an application/json object, at most 64 KiB. A hook admits at most 60 accepted deliveries per rolling minute across instances. Retries within seven days return the original run ID with HTTP 200 and duplicate: true. A successful new delivery returns 202 with deliveryId and runId. A missing contact in skip mode returns 202 with accepted: false and subject_not_found. Bad authentication returns 401, malformed input 400, wrong content type 415, oversized bodies 413, and rate limits 429 with Retry-After. Unknown/disabled hooks and disabled automation features use the router's 404.
Use a JSON pointer such as /customer/email to resolve an email or /contactId to resolve an existing contact ID in this organization. Emails are trimmed, lowercased and validated. Create mode is available only for email matching. Up to twenty JSON pointer mappings can write scalar values to existing contact custom fields, using the same typed validation as the CRM. Dry runs never create contacts or write mapped fields; an absent contact is rejected even in create mode. Existing contacts receive normal dry_run workflow histories. Normal engine record and organization hour caps remain active.
Only this workflow receives the workflow.webhook event. Outbound webhook and lifecycle expansion actions are refused on inbound webhook workflows. Ordinary CRM effects can still produce their own normal CRM events.
HMAC keys are envelope encrypted with the configured vault KEK: hashing alone would make signature verification impossible. Token mode stores only SHA256. GET and automation_hook_get return metadata and the twenty latest delivery outcomes, never keys or payload values. Payload JSON is retained up to 16 KiB; larger bodies retain a truncation marker and byte count. Deliveries, including their dedupe identities, expire after seven days through the existing automation wait sweep. No new scheduler is needed.
Use automation_hook_create and automation_hook_get through MCP for the same operations and permissions as REST. Creation returns the new secret once; keep that response out of transcripts and logs.
The parser and transaction locking follow the official Fastify parser documentation and PostgreSQL advisory lock documentation.