HTTP Trigger Trigger a workflow from any external HTTP request. The HTTP trigger exposes a unique public URL for your workflow. Any system that can send an HTTP request — Zapier, Make, another service, your own backend — can trigger it. The trigger URL Each workflow gets a unique URL shown in the editor under Trigger → HTTP Trigger. The URL includes a secret token that authenticates the request, so you do not need to add your own authentication unless you want additional validation. Caution: Treat your trigger URL as a secret. Anyone with the URL can trigger your workflow. The data object { // Parsed JSON body (or null if the body is not valid JSON) ...bodyFields, // URL query parameters are merged into data at the top level // e.g. ?foo=bar makes data.foo === 'bar' } The entire parsed JSON body is spread into data at the top level. Query string parameters are also available on data. You can access them directly: export class Workflow { async start(data, headers, api) { console.log('Order ID from body:', data.orderId); console.log('Source from query string:', data.source); } } Returning a custom response The return value of your start step becomes the HTTP response sent back to the caller. Return a plain object — serialised as JSON with Content-Type: application/json: async start(data, headers, api) { // ... do work ... return { received: true, id: data.orderId }; } // Caller receives: {"received":true,"id":"12345"} Return a Response object — full control over status, headers, and body: async start(data, headers, api) { if (!data.orderId) { return new Response('Missing orderId', { status: 400 }); } // ... do work ... return new Response('Accepted', { status: 202 }); } Return nothing — caller receives {"success":true}: async start(data, headers, api) { // fire and forget } Note: Only the start step's return value is sent to the caller. Any subsequent steps scheduled with api.scheduleNextStep() run asynchronously after the response has already been sent. Example — validate and enqueue export class Workflow { async start(data, headers, api) { if (!data.orderId | | !data.action) { return new Response( JSON.stringify({ error: 'Missing required fields' }), { status: 400, headers: { 'content-type': 'application/json' } } ); } // Schedule heavy processing asynchronously await api.scheduleNextStep({ delay: 10, action: 'processOrder', payload: { orderId: data.orderId, action: data.action } }); return { queued: true, orderId: data.orderId }; } async processOrder(data, headers, api) { // This runs 10 seconds later, after the HTTP response was already returned console.log('Processing order', data.orderId); } }