Skip to content

HTTP Trigger

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.

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.

{
// 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:

class Workflow {
async start(data, headers, api) {
api.log('Order ID from body:', data.orderId);
api.log('Source from query string:', data.source);
}
}

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
}
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
api.log('Processing order', data.orderId);
}
}