Skip to main content
onHttpRequest creates an HTTP endpoint. Each declaration gets a unique route by default; scope: "automation" or scope: "project" shares a route at that scope. The endpoint accepts cross-origin browser requests from any origin and answers cross-origin resource sharing (CORS) preflight requests. Browser credentials aren’t supported.

Example

automations/http-webhook.automation.ts
The body option accepts any Standard Schema implementation, not only Zod. The schema output becomes the type of request.body, so nested properties are signals you can pass directly to actions. The schema must run synchronously. A schema that returns a promise fails the run. request.endpoint is the deployed trigger URL as a static string. Use it as another service’s callback or webhook URL. For a callback URL that only a provider should invoke, enable callback protection and sign the endpoint from the action that registers it.

Options

onHttpRequest configuration is static and can’t use signals. When the trigger doesn’t wait for a response, the endpoint accepts the event with 202 and returns:

Trigger data

onHttpRequest returns an HTTP request signal with static endpoint: string and this request data: onHttpRequest decodes application/json and *+json as JSON. It decodes text/*, JavaScript, XML, YAML, TOML, NDJSON, JSON text sequences, and SQL media types as strings without parsing their contents. Text uses the character encoding declared in content-type. XML selects its encoding from the byte order mark first, then the media type’s character encoding, then the XML encoding declaration. URL-encoded and multipart forms become objects. Repeated field names become arrays, and multipart uploads become File values with their filenames and media types. Multipart forms accept up to 1,000 parts and 8 KiB of headers per part. An empty body becomes null. Unknown or binary media types stay as Uint8Array. The endpoint returns 400 for malformed JSON or multipart bodies and for text or XML with invalid byte sequences before creating a run. It returns 413 when a multipart body exceeds the header or part-count limits and 415 for an unsupported character encoding. A supplied Standard Schema validates after the run starts, so a schema mismatch fails that execution. onHttpRequest omits cookie, cf-*, sec-*, and x-forwarded-for headers from durable request data. You can’t authenticate a custom webhook that requires one of those headers. Passing request.requestId to respondToHttpRequest makes onHttpRequest wait unless you explicitly set waitForResponse: false. You can explicitly set true when waiting is required but planning can’t infer the target. Responses are matched by request ID, including across correlated contexts. The endpoint waits up to 55 seconds. If execution finishes without its addressed response, it returns 500. If execution is still active after 55 seconds, it returns 504, and execution can continue after the caller times out.

Protect a provider callback

Generate a signed URL inside an action anchored to the occurrence that registers the provider callback:
automations/prepare-provider-callback.automation.ts
The example marks the initiating run significant after generating the protected URL without changing the provider. In production, pass prepared.url to the provider registration action instead. runtime.createCallbackUrl() returns a signed, expiring bearer URL bound to this automation and exact trigger endpoint. The runtime rejects missing, altered, expired, or incorrectly targeted capabilities before creating a context. Keep the URL secret. It remains reusable so providers can retry delivery. A valid request still starts an independent root context. Protection authorizes access to the endpoint. It doesn’t connect the callback to the action that created the URL. Include a provider job ID in both streams and correlate them. Callback protection strips its query parameter before exposing the request’s url and query values.