Triggers and the response
A flow has exactly one trigger, and it decides when the flow runs.
Webhook
Every flow with a webhook trigger has its own address with a token:
POST https://app.oxta.io/webhook/<flow id>/<token>
The trigger output is headers, query, body, method, path, timestamp. Read it by trigger name: {{ outputs.incoming.body.title }}.
When the caller waits for an answer
By default a webhook answers {"ok": true} at once and the flow finishes in the background. A caller that wants a real answer asks for it in the request:
| Request | What happens |
|---|---|
| no signal | {"ok": true} at once, flow continues in the background |
?wait=1 | waits for the Response node and returns it |
Prefer: wait=10 | the same through RFC 7240, with 10 seconds as the limit |
X-Oxta-Wait: 1 | the same when the address cannot be changed |
Prefer: respond-async | never wait, even with ?wait=1 |
The wait is 15 seconds by default, 30 at most. After that the caller gets 504, but the flow is not cancelled and runs to the end.
The Response node builds the answer: status, headers, body with {{expressions}}. The first response wins — with a Response on several branches, whichever ran first is returned. Put a Response on the error branch to return a meaningful failure.
Form
The Form trigger starts a flow from fields a person fills in. The node describes the fields: name, label, type (text, multiline text, number, yes/no, a choice from options, date) and whether each is required. The form opens on the flow's Run page (/flows/<id>/run) and in the test run inside the editor. Answers reach the flow as input.form.<name>, already coerced: a number is a number, a switch is true or false, a date is YYYY-MM-DD. An empty required field or an option that is not offered stops the run before it starts, and the error shows under the field. Example: a leave request with "employee", "days" and "from" → Slack to the manager → a row in Google Sheets. Only the account owner sees the form for now; public forms on sites come later.
Schedule
The cron trigger takes a five-field expression and an IANA zone:
0 9 * * 1-5 at 09:00 on weekdays
*/15 * * * * every 15 minutes
0 0 1 * * on the first of each month
Never finer than a minute. The zone defaults to UTC, so set Europe/Kyiv if you mean Kyiv.
Rate limit
Flow settings can cap how many requests pass per window. Above the cap the webhook answers 429 with Retry-After. Without a setting the platform default applies: 60 requests per minute per flow. On top of that, all webhooks of one account together may not exceed 600 requests per minute. Set a tighter limit for any flow whose address is public.