Skip to Content
Task guidesTechnical: Triggers

Triggers

Technical reference. This page is for integrations, advanced configuration, or platform operations. For portal tasks, start with the user guide.

Triggers bind a workload to an automation rule. In the current implementation, trigger bindings are always attached to a workload, point at a flow by slug, and target a specific environment.

Manage triggers in the workload’s Triggers tab: open the workload and choose Triggers to list, create, edit, and delete its bindings.

Current trigger model

The route prefix is:

/v1/workloads/{workload_id}/triggers

But trigger payloads use workload_id in the response body.

Each trigger binding has:

FieldDescription
trigger_binding_idSystem-generated UUID.
workload_idThe workload this trigger belongs to.
nameOperator-friendly name for the binding.
flow_slugFlow asset slug executed when the trigger fires.
environmentTarget environment such as dev or production.
trigger_typeOne of schedule, webhook, or event.
enabledWhether the trigger is active.
descriptionOptional operator-facing description.
next_fire_atNext scheduled run for schedule bindings.
last_fired_atTimestamp of the last successful fire.
last_errorLast dispatch error, if any.

Trigger configuration blocks

Exactly one config block is active per trigger binding.

Schedule triggers

{ "trigger_type": "schedule", "schedule": { "cron": "0 9 * * 1-5", "timezone": "UTC", "input_payload": { "report_type": "daily" } } }
FieldDescription
cronCron expression used for scheduling.
timezoneIANA timezone for schedule evaluation.
input_payloadStatic payload merged into the dispatch request.

Webhook triggers

{ "trigger_type": "webhook", "webhook": { "path": "github/push", "signing_secret": "replace-me", "signature_header": "x-hub-signature-256", "input_payload": { "source": "github" } } }
FieldDescription
pathManaged webhook path under /v1/triggers/webhooks/....
signing_secretShared secret used for HMAC verification.
signature_headerHeader that carries the signature.
input_payloadStatic payload merged with the webhook event payload.

Event triggers

{ "trigger_type": "event", "event": { "topic": "orders.completed", "source_filter": { "service": "checkout" }, "input_payload": { "pipeline": "order-followup" } } }
FieldDescription
topicInternal topic consumed by the trigger.
source_filterOptional structured filter applied to the event payload.
input_payloadStatic payload merged into each dispatch.

API reference

Base URL: http://localhost:8000

Create a trigger binding

curl -X POST http://localhost:8000/v1/workloads/{workload_id}/triggers \ -H "Content-Type: application/json" \ -d '{ "name": "daily-report", "flow_slug": "daily-report-flow", "environment": "production", "trigger_type": "schedule", "enabled": true, "description": "Generate the daily executive report", "schedule": { "cron": "0 9 * * 1-5", "timezone": "UTC", "input_payload": { "report_type": "daily" } } }'
{ "trigger_binding_id": "t1a2b3c4-0000-0000-0000-000000000001", "workload_id": "a1b2c3d4-0000-0000-0000-000000000001", "name": "daily-report", "flow_slug": "daily-report-flow", "environment": "production", "trigger_type": "schedule", "enabled": true, "description": "Generate the daily executive report", "schedule": { "cron": "0 9 * * 1-5", "timezone": "UTC", "input_payload": { "report_type": "daily" } }, "next_fire_at": "2026-04-11T09:00:00Z", "last_fired_at": null, "last_error": null, "created_at": "2026-04-10T14:00:00Z", "created_by": "user:alice", "owner_ref": "user:alice", "updated_at": "2026-04-10T14:00:00Z" }

The control plane validates that the referenced flow exists and that the flow’s trigger.type matches the trigger binding type.

List trigger bindings

curl http://localhost:8000/v1/workloads/{workload_id}/triggers

Get a trigger binding

curl http://localhost:8000/v1/workloads/{workload_id}/triggers/{trigger_binding_id}

Update a trigger binding

curl -X PATCH http://localhost:8000/v1/workloads/{workload_id}/triggers/{trigger_binding_id} \ -H "Content-Type: application/json" \ -d '{ "enabled": false }'

The update endpoint re-validates the full trigger shape after applying your patch.

Transfer ownership

owner_ref is the binding’s current owner. It defaults to whoever created the binding and is what a scheduled run’s result read authorizes against, so the owner is the person who can read what their schedule produced. created_by sits beside it as the immutable record of who created the binding and is never used for authorization.

Transfer the binding by patching owner_ref on its own:

curl -X PATCH http://localhost:8000/v1/workloads/{workload_id}/triggers/{trigger_binding_id} \ -H "Content-Type: application/json" \ -d '{ "owner_ref": "user:bob" }'

An owner-only patch is a metadata edit: it leaves next_fire_at, the drift baseline, the failure count, and the circuit breaker untouched, so transferring a schedule never reschedules it or re-arms a tripped breaker. Combining owner_ref with any other field takes the normal update path, which does re-activate the trigger.

Because the new owner gains read access to the schedule’s future results, the target must already be a member of the workspace who can view executions. owner_ref cannot be set when creating a binding — the creator is always the initial owner.

Delete a trigger binding

curl -X DELETE http://localhost:8000/v1/workloads/{workload_id}/triggers/{trigger_binding_id}

Ingress endpoints

Webhook ingress

Webhook traffic is delivered to:

POST /v1/triggers/webhooks/{path}

Requests must include the configured signature header and an x-orqestra-timestamp header containing canonical ASCII Unix seconds. The timestamp must be within the binding’s configured skew window, and the timestamp plus optional x-orqestra-delivery-id (1–256 UTF-8 bytes without control characters) are included in the signed input for replay protection. The signature is lowercase hex, optionally prefixed with sha256=. Missing or malformed headers, stale timestamps, invalid UTF-8 bodies, and exhausted admission buckets are rejected before the signing secret is read from Vault.

The public route consumes two independent Redis-backed limits: the opaque server-derived source bucket and the exact binding bucket. Configure their defaults with ORQESTRA_TRIGGER_WEBHOOK_SOURCE_RATE_LIMIT, ORQESTRA_TRIGGER_WEBHOOK_BINDING_RATE_LIMIT, and ORQESTRA_TRIGGER_WEBHOOK_RATE_LIMIT_WINDOW_SECONDS. Rate-limit and dependency failures return bounded, value-free error responses; the route never echoes the peer address, lookup path, or secret reference.

Example:

curl -X POST http://localhost:8000/v1/triggers/webhooks/github/push \ -H "Content-Type: application/json" \ -H "x-hub-signature-256: <computed-signature>" \ -H "x-orqestra-timestamp: <unix-seconds>" \ -d '{ "ref": "refs/heads/main", "repository": { "full_name": "my-org/my-repo" } }'

Response:

{ "trigger_binding_id": "t1a2b3c4-0000-0000-0000-000000000001", "flow_slug": "daily-report-flow", "outcome": "success", "execution_id": "exec-123", "decision_id": null }

Event ingress

Internal trigger events are published to:

POST /v1/triggers/events/{topic}

Example:

curl -X POST http://localhost:8000/v1/triggers/events/orders.completed \ -H "Content-Type: application/json" \ -d '{ "service": "checkout", "order_id": "ord-123" }'

Response:

{ "topic": "orders.completed", "published_to_bus": true, "dispatched_trigger_binding_ids": ["t1a2b3c4-0000-0000-0000-000000000001"], "retryable_release_pin_conflict_binding_ids": [] }

If an event trigger hits a retryable release-pin conflict during dispatch, the binding is omitted from dispatched_trigger_binding_ids and listed in retryable_release_pin_conflict_binding_ids instead. The binding keeps last_error: "release_pin_conflict" so operators can distinguish a retryable rollout-window skip from a generic dispatch failure.

Schedule tick endpoint

Schedule execution is advanced by:

POST /v1/triggers/schedule-tick

This is primarily for local development, tests, and simple deployed schedulers.

curl -X POST http://localhost:8000/v1/triggers/schedule-tick \ -H "Content-Type: application/json" \ -d '{ "now": "2026-04-11T09:00:00Z" }'
{ "processed_at": "2026-04-11T09:00:00Z", "dispatched_trigger_binding_ids": ["t1a2b3c4-0000-0000-0000-000000000001"] }

Operational notes

  • Trigger bindings can only be configured for workloads whose status is registered AND whose aggregate runtime readiness is ready (an invocation mode, a bound service lane, an active release, and any required handoffs — lifecycle alone is not enough).
  • Webhook paths must be unique across webhook trigger bindings.
  • A trigger binding references flows by flow_slug, not by release binding role.
  • There is no separate per-trigger manual dispatch endpoint in the current public API. Webhooks, events, and schedule ticks are the supported dispatch surfaces.