Trigger
triggers
JSON:API type: trigger.
The v2 OpenAPI document declares this resource's schema; the resource-field coverage gate holds this page to it.
A trigger is one event-automation rule, scoped under a project: its match
half (subject, events, scope_path, conditions) decides which stored events it
fires on, and its action half (action_type, action_params,
throttle_per_minute) says what each firing creates. Each firing is recorded
as a trigger_firing resource (opschain docs resources/trigger_firing).
Endpoints
| Verb | Path | Behaviour |
|---|---|---|
GET | /api/projects/{project_code}/triggers | Index, code ascending. Each trigger is gated by read on the project's …/triggers rule path; meta.authorisations reports update/delete on that path. |
POST | /api/projects/{project_code}/triggers | Create — project readable plus update on …/triggers, 404-on-deny. 201, or 422 with the model errors. |
GET | /api/projects/{project_code}/triggers/{id} | Show. A missing project, a trigger outside the project, or a read denial on the trigger's own rule path (…/triggers/<code>) all answer 404. |
PATCH/PUT | /api/projects/{project_code}/triggers/{id} | Update — requires update on the trigger's rule path. The merged (stored + supplied) state is validated, so a partial update cannot leave the row inconsistent. |
DELETE | /api/projects/{project_code}/triggers/{id} | Hard delete (firings cascade with the row) — requires delete on the trigger's rule path. 204. |
GET | /api/projects/{project_code}/triggers/{id}/firings | The trigger's firings, newest first. |
POST | /api/projects/{project_code}/triggers/{id}/test | Dry-run against one stored event (body attribute event_id), gated like show. Writes nothing; answers a trigger_test resource (below). |
Triggers are also reachable through the node-path dispatch
(GET /api/projects/{project_code}/triggers[/{id}] resolved via the
node-path routing table) — the project-level route only.
Attributes
| Attribute | Type | Meaning |
|---|---|---|
code | string | The trigger's unique name within the project (^[a-z0-9_]+$, unique per node). Immutable after create (not in the update permit list). Also the tail of the trigger's RBAC rule path. |
name | string | Display name; defaults to the code when blank on create. |
description | string, nullable | Free text; null when never set. |
enabled | boolean | Whether the engine fires it. Defaults true on create. A disabled trigger is still evaluated by the test endpoint (the report notes it). |
subject | string | What kind of event source it matches: one of change, workflow_run, step, artifact, external (verbatim validation message: "Subject must be one of change, workflow_run, step, artifact, external"). artefact is accepted at the edge and stored as the canonical artifact. |
events | array of strings | The event names to match: the friendly lifecycle names created, started, finished, error, cancelled, or a namespaced custom event type matching ^[a-z0-9_]+:[a-z0-9_:]+$ (reserved prefixes such as api:/system: stay matchable; only emission of them is refused). A leading artefacts:/api:artefacts: segment is normalised to artifacts:. Must be non-empty. |
scope_path | string, nullable | Node-path scope restricting the match; null means unscoped within the project. |
conditions | array of strings (JSON, served verbatim as stored) | Flat "<path> <op> <value>" strings: path under event., operator one of eq, ne, in, contains. Validated on write, stored verbatim, interpreted at fire time. Defaults []. |
action_type | string | What a firing creates: change or workflow_run (verbatim message: "Action type must be either change or workflow_run"). |
action_params | object (JSON, served verbatim as stored) | The creation payload. For change: requires parent_path starting with / and a non-empty action. For workflow_run: requires a non-empty workflow; optional version pins a positive workflow version number (or an event template) — omitted means the latest published version at firing time. Values may carry ${{ event.* }} templates resolved per firing. An inputs map supplies the created run's typed inputs — its values may carry ${{ event.* }} templates, so event fields map onto the declarations, and the resolved values validate at the firing's run creation exactly like a user-supplied inputs object (a violation fails the firing). Other keys pass through. Defaults {}. |
throttle_per_minute | integer | Per-trigger firing throttle, minimum 1, column default 60. |
run_as | string, nullable | The identity firings execute as. A write that sets (or an update that retains) one requires the acting author's explicit act_as trust grant covering the trigger's project path, and the identity must resolve to a usable principal (disabled or break-glass accounts refuse; service accounts are the durable choice for team automations). Blank/"" clears it. |
owned_by | string, nullable | The group owning this automation: maintenance and failure-notification accountability routes to the team, and the firing-identity warn events carry it. Must name a known group (local or provider snapshot) — an unknown group is a named 422. Blank/"" clears it. |
created_by | string | Username of the creating user (joined from users). |
created_at / updated_at | string (ISO8601, 6 fractional digits) | Row timestamps. |
Write semantics: a supplied null on an attribute is treated as not supplied
and preserves the stored value; nullable text fields clear on a supplied
blank string instead.
Relationships and links
| Name | Kind | Meaning |
|---|---|---|
parent | to-one project | The owning project, with a related link to /api/projects/<code>. |
links.self | link | /api/projects/<code>/triggers/<id> |
links.firings | link | self + /firings |
The test report (trigger_test)
POST …/test answers a resource of type trigger_test whose attributes are
the dry-run verdict, gate by gate: matched, enabled,
subject_and_event_match, scope_match, conditions (per condition:
condition, holds, actual), action_params_resolved (the resolved
templates on a match, null otherwise or on a template failure),
template_error (nullable), would_fire. matched deliberately excludes
enabled, so a disabled trigger still reports what it would have matched. A
missing event answers a named 404 pointing out that a correlation id is not
an event id.
The v2 service — TriggerService
ListTriggers / GetTrigger / CreateTrigger / UpdateTrigger /
DeleteTrigger / ListTriggerFirings / TestTrigger /
DiscardTriggerFiring carry this surface typed, with the v1 create
defaults, merged-state validation, run_as write-time authority and the
canonical artifact spelling normalisation. See
opschain docs api-v2.
Related pages
opschain docs resources/trigger_firing— the firing record, including the maintenance-deferred arm.opschain docs triggers— the component page (match/fire engine).opschain docs maintenance-windows— how an active window defers firings.