Buni.aiDocs

Scheduling

Run a chatbot flow or automation at a set time with runAt or delaySeconds, then cancel or reschedule it before it starts.

The async trigger endpoints can hold a run until a time you choose: a reminder the day before an appointment, a follow-up 30 minutes after a cart is abandoned. You get an invocationId back immediately and can cancel or move the run until it starts.

Where scheduling works

runAt and delaySeconds work on POST /flows/{projectId}/trigger-async and POST /automations/{projectId}/trigger-async. The sync endpoints and POST /bots/{projectId}/invoke ignore them and run straight away.

For a repeating schedule (every day at 08:00), use a Schedule trigger in the automation instead. See Automation triggers.

Schedule a run

Send one of these in the request body:

FieldTypeRule
runAtISO 8601 date-timeMust be in the future. Include Z or an offset, for example 2026-10-01T08:00:00+00:00.
delaySecondsnumberMust be greater than 0. The run starts that many seconds from now.
curl -X POST "https://www.buni.ai/api/v1/orgs/$ORG_ID/automations/$PROJECT_ID/trigger-async" \
  -H "Authorization: Bearer $BUNI_API_TOKEN" \
  -H "Content-Type: application/json" \
  -H "x-idempotency-key: appt-7781-reminder" \
  -d '{
    "event": "appointment.reminder",
    "payload": { "appointmentId": "7781", "phone": "+233201234567" },
    "runAt": "2026-10-01T08:00:00Z"
  }'

The response is 202 with status SCHEDULED:

{
  "invocationId": "clx9km1a40031ab12cd34ef41",
  "status": "SCHEDULED",
  "scheduledFor": "2026-10-01T08:00:00.000Z"
}

Store the invocationId: you need it, and the same token, to change the run.

Error (400)Cause
Provide either runAt or delaySeconds, not bothBoth fields sent.
runAt must be a valid ISO date-timerunAt could not be parsed.
runAt must be in the futurerunAt is now or in the past.
delaySeconds must be a positive numberZero, negative or not a number.

What happens at run time

At scheduledFor the run moves to RUNNING and finishes like any async run. Your monthly quota is checked again at that moment. If you passed webhookUrl, the callback follows. See Async runs and callbacks.

A scheduled run is not checked against the Trigger node's trigger key and expected payload when it fires. Check the payload with a "dryRun": true call when you schedule it.

If Enable External API is off when the run comes up, the run fails.

Reschedule a run

Send PATCH with "action": "reschedule" and a new runAt or delaySeconds. The same rules apply as when scheduling.

curl -X PATCH "https://www.buni.ai/api/v1/orgs/$ORG_ID/external-invocations/$INVOCATION_ID" \
  -H "Authorization: Bearer $BUNI_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"action": "reschedule", "runAt": "2026-10-02T08:00:00Z"}'

The response is the full invocation with the new scheduledFor.

Cancel a run

curl -X PATCH "https://www.buni.ai/api/v1/orgs/$ORG_ID/external-invocations/$INVOCATION_ID" \
  -H "Authorization: Bearer $BUNI_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"action": "cancel"}'

The run's status becomes CANCELLED and it never runs. The response is the full invocation.

When a change is refused

Cancel and reschedule only work on async runs that have not started. Otherwise the call returns 409:

ErrorCause
Only scheduled invocations can be modifiedThe run is already queued, running or finished, or was cancelled.
Only async invocations can be modifiedThe run came from a sync endpoint.
Invocation is no longer scheduledThe run started while your request was in flight.

approve and reject actions on the same endpoint are for runs paused at an Approval node. They need a signed-in user with edit access to the project, so an API token cannot use them. See Approvals.

Last reviewed 24 September 2026

On this page