Skip to main content
See also: Triggers concept and configuration for what this API powers, when to call it, and how it is configured.

GET /api/v1/triggers

List all trigger rules sorted by priority descending.

Query Parameters

Response


POST /api/v1/triggers

Create a new trigger rule.

Request Body

Condition shape. A leaf rule is { "field": "<payloadKey>", "operator": "<op>", "value": <any> }; rules combine into groups with all (AND) or any (OR) — e.g. { "all": [ { "field": "amount", "operator": "gt", "value": 500 }, { "any": [ ... ] } ] }. Operators: eq, neq, gt, gte, lt, lte, in (value must be an array), exists. An unknown operator fails closed (the rule does not match). An empty or omitted condition always fires.

Example

Response: 201 Created

GET /api/v1/triggers/

Get trigger rule details.

PUT /api/v1/triggers/

Update a trigger rule. Only provided fields are updated. Response: 200 OK

DELETE /api/v1/triggers/

Delete a trigger rule. Requires admin role. Response: 204 No Content

POST /api/v1/triggers//test

Dry-run a trigger against a sample event payload. Returns whether the trigger would fire without actually executing the action.

Request Body

Response


POST /api/v1/triggers/file-arrival

Push-based webhook that fires a data pipeline when a file lands. Unlike the trigger-rule endpoints above, this is a system webhook: it is not RBAC-gated — it self-authorizes with the shared CRON_SECRET. Rate limited to 60 requests / minute per source IP. Returns 503 if CRON_SECRET is not configured.

Authentication

One of:
  • Authorization: Bearer <CRON_SECRET> header
  • X-Cron-Secret: <CRON_SECRET> header
  • secret field in the request body (per-pipeline override; takes precedence)
  • A same-origin request carrying a valid session cookie (the editor’s “Fire now” button)

Request body

Two shapes are accepted:
For the EventBridge shape the route matches the (bucket, key) pair against every active irVersion: "1.0" pipeline that has a file_arrival trigger, and probes the source’s pattern to confirm the key really matches before dispatching.

Behavior

The route confirms the resolved pipeline actually has a file_arrival trigger and belongs to the asserted tenant, writes a PipelineRun row (triggerSource: "file_arrival"), then dispatches the run in-process (fire-and-forget). Poll GET /api/v1/pipelines/{id}/runs for the outcome.
Push and poll can’t double-load the same file. A pipeline may have both this webhook and the in-process scheduler polling the same inbox. Both paths claim the run under a transaction-scoped advisory lock keyed on (tenant, pipeline, objectKey) and stamp metadata.objectKey on the run row; a claim first checks for an in-flight run with the same objectKey. So for a given object, whichever path fires first wins and the other is a no-op — the file is loaded exactly once regardless of how many triggers observe it.

Response 202

Errors


POST /api/v1/triggers/eventbridge

Direct receiver for AWS EventBridge API Destinations that proxies to a /api/v1/cron/* endpoint — an alternative to the Terraform Lambda hop for operators who prefer fewer moving parts. Not RBAC-gated; authenticated with CRON_SECRET / CRON_TOKEN.

Authentication

  • HMACX-EventBridge-Signature: <hex> = HMAC-SHA256(CRON_SECRET, rawBody) (preferred), or
  • Shared secretX-Cron-Token, X-Cron-Secret, or Authorization: Bearer equal to the secret.
Returns 401 (no body detail) when the secret is unset or verification fails.

Request body

cron_endpoint_path must be in the route’s allowlist (the /api/v1/cron/* jobs plus the legacy /api/cron/tick); anything else returns 400. On a match the route self-calls that cron endpoint (GET, forwarding the secret) and returns its result.

Response

The HTTP status mirrors the downstream cron response. 400 = path not in allowlist, 502 = the downstream self-call failed.

Roles

The trigger-rule endpoints are RBAC-gated: The file-arrival and eventbridge webhooks are not RBAC-gated — they self-authorize with CRON_SECRET as described above. See also: Triggers