Skip to main content
A trigger is the immutable audit record of what caused a run. Every time a definition runs — whether you called the API, a webhook delivery arrived, a schedule fired, or an internal event matched — GetDialed writes exactly one trigger, then produces the rest of the run chain from it: Trigger → Batch → Job → Execution (the batch is the rollup, one job per record, one execution per job). Triggers are write-once: they are never updated or deleted. A trigger that failed to spawn a batch is still a valid audit record — the anchor exists so you can always answer “where did this run come from?” long after the run itself has aged out.

Type vs. source

A trigger carries two independent dimensions. They are not the same field, and they filter separately: Type answers which entry point created this run and is always populated. Source answers which upstream system or workflow the caller attributed it to and is nullable — the platform never infers it. A nightly cron and a manual UI click can both carry source: "ui" while differing in type; a webhook and an API call can share type semantics while differing in source.
The type and source values are denormalized onto every batch, job, and execution (trigger_type, trigger_source), so a runs feed can filter or group by either dimension without a second lookup against the trigger.

The read-only surface

Triggers are created only as a side effect of a run — there is no POST, PUT, or PATCH. The /flows/triggers surface is read-only: Every route is tenant-scoped: a missing or cross-tenant trigger returns 404 (never 403). The nested /flows/triggers/{trigger_id}/batches route verifies you own the parent trigger before listing its children.
Today a trigger maps to exactly one batch (1:1). The nested GET /flows/triggers/{id}/batches route is shaped as a list so it stays forward-compatible with future record-partitioning, where one trigger may fan out into several batches.

raw_request is admin-only and detail-only

Every trigger stores the raw inbound payload that caused it — the webhook body, the event envelope, or the API trigger request. This blob can hold PII, HMAC signatures, and arbitrary caller data, so it is doubly gated:
  • Detail-only. raw_request is returned only on GET /flows/triggers/{trigger_id}. It is omitted entirely from every list response — it never appears in GET /flows/triggers or GET /flows/triggers/{id}/batches items.
  • Admin-only. Even on the detail route, raw_request is included only for an admin principal (an X-API-Key is admin-equivalent, or a Clerk JWT with the admin role). Non-admin callers get the trigger’s type, source, timestamps, and back-references — but not the raw blob.
raw_request is the audit-forensics escape hatch. Its blast radius is deliberately minimized: it is the single field on the entire read surface that is both admin-gated and detail-only. Non-admin principals and every list view never see it.

Next steps

Batches, jobs, and executions

How a trigger becomes a batch, its per-record jobs, and their executions.

How GetDialed works

The core objects — definitions, triggers, batches, jobs, and executions.