Documentation menu

API reference

7 operations in automations. Raw spec: openapi.json.

GET/api/v1/automation-rules

GET /api/automation-rules

Responses

StatusDescription
200

Security: bearer

POST/api/v1/automation-rules

POST /api/automation-rules — documents are validated through core-domain BEFORE storage, so stored rules are always well-formed (malformed rules can only arrive out-of-band and are skipped at evaluation time).

Request body

CreateRuleRequest

Responses

StatusDescription
200

Security: bearer

POST/api/v1/automation-rules/draft-summary

POST /api/v1/automation-rules/draft-summary — stream a one-sentence summary of the rule draft.

Admin-gated (Edit). NOT a write: it returns an SSE stream of frames and persists nothing. Refusals answer typed BEFORE any stream begins, so the client branches on the status code and renders a not-available state instead of a dead spinner.

Request body

AutomationDraftSummaryRequest

Responses

StatusDescription
200SSE stream of summary frames (text/event-stream)
400validation
403typed refusal: ai_surface_not_granted | ai_surface_disabled | ai_model_not_allowed | ai_no_models_configured | ai_hard_cap_reached | ai_no_credential (the org master switch among them)

Security: bearer

PATCH/api/v1/automation-rules/{id}

PATCH /api/automation-rules/{id}

Parameters

NameInTypeRequiredDescription
idpathstringYes

Request body

UpdateRuleRequest

Responses

StatusDescription
200

Security: bearer

DELETE/api/v1/automation-rules/{id}

DELETE /api/automation-rules/{id}

Parameters

NameInTypeRequiredDescription
idpathstringYes

Responses

StatusDescription
200

Security: bearer

POST/api/v1/automation-rules/{id}/test-run

automation_rules_test_run

Parameters

NameInTypeRequiredDescription
idpathstringYes

Responses

StatusDescription
200
404rule not visible in scope
422stored rule document is malformed

Security: bearer

POST/api/v1/internal/effects

POST /api/internal/effects — applies automation-rule effects to one ticket through the SAME write paths users go through (ticket patch, comment insert, notification fan-out), emitting every corresponding domain event tagged `via_automation` so evaluators never loop.

The subject may be ticket-less (Wave 43 lane 3): a board-scoped rule whose envelope carried no ticket. Then the board is resolved for scope and only subject-agnostic effects (notifications) run — every ticket-writing effect skips with a warn, never fails the batch, so one bad rule can never wedge the queue. # The batch runs as the rule's author (Wave 58 lane `p58-effects-seam`) The token is one deployment-wide bearer, so before this lane the request's `org_id` was both the RLS scope and the actor: the holder of the token could name any org and write there with no permission check. The principal is now the author recorded on `automation_rules.created_by`, resolved into a full [`Principal`] exactly as a session builds one, and the grant a manual write would need is applied before dispatch ([`effects_authority`]). A rule with no author is refused rather than attributed: the remedy is an admin re-saving it, which records the editor as the author. The batch's action list must be the rule's own, so a rule id authorises that rule's effects and not the author's whole authority. Every refusal is a typed 4xx with an `automation.effects_denied` audit row, and nothing the batch asked to write survives: the identity and matrix gates refuse before the write transaction opens, and a board denial rolls it back.

Request body

EffectsRequest

Responses

StatusDescription
200