REST API
The v1 HTTP surface used by server SDKs. Framework adapters expose an allowlisted, identity-aware subset from your application's /api/incld/v1 route.
Conventions
| Concern | Contract |
|---|---|
| Base URL | https://api.incld.dev/v1 |
| Authentication | Authorization: Bearer <project secret key> |
| Tenant scope | Incld-Organization-Id selects one customer organization; adding Incld-User-Id narrows it to one end user. Framework proxies set both from trusted session context |
| Media type | application/json; request and response fields use snake_case |
| Pagination | limit 1–100 plus opaque cursor; responses include meta.next_cursor and meta.has_more |
| Idempotency | Idempotency-Key on create, decision, and manual Audit writes |
| Dates | RFC 3339 timestamps in UTC; recurrence timezone values are IANA names |
| Component access | A component_not_enabled error is returned when the project lacks the required entitlement |
{
"data": [],
"meta": { "next_cursor": null, "has_more": false }
}
Browser applications do not call this origin with a secret key
/api/incld/v1/*
and point IncldBrowser
or IncldProvider
at /api/incld. The adapter removes identity fields supplied by the browser and injects trusted server context.
A raw project key is an administrator credential
Incld-Organization-Id, optionally add Incld-User-Id, and never accept either value directly from an end-user request. A user header without an organization is rejected.
Actions, schedules, and runs
/actions
List action definitions.
Request and response schemas
Query parameters
| Field | Type | Required | Description |
|---|---|---|---|
| limit | integer 1..100 | No | Page size; defaults to 25. |
| cursor | string | No | Opaque next_cursor returned by the previous page. |
Request body
No JSON request body.
Response 200 · ActionPage
Action definitions returned.
| Field | Type | Required | Description |
|---|---|---|---|
| data[].id | uuid | Yes | Action UUID. |
| data[].identifier | string | Yes | Stable action identifier. |
| data[].display_name | string | Yes | Human-readable label. |
| data[].description | string | null | No | Developer-facing description. |
| data[].payload_schema | object | Yes | Declared JSON payload schema. |
| data[].configuration | object | Yes | Action configuration. |
| data[].inserted_at | date-time | Yes | Creation timestamp. |
| data[].updated_at | date-time | Yes | Last update timestamp. |
| meta.next_cursor | string | null | Yes | Opaque cursor for the next page. |
| meta.has_more | boolean | Yes | Whether another page is available. |
Error responses use the shared error envelope.
/actions
Define or update an action by identifier.
Request and response schemas
Request body · ActionInput
| Field | Type | Required | Description |
|---|---|---|---|
| identifier | string | Yes | Stable identifier used by schedules and Bulk. |
| display_name | string | Yes | Human-readable label. |
| description | string | null | No | Developer-facing description. |
| payload_schema | object | No | JSON Schema for action payloads; defaults to {}. |
| configuration | object | No | Action-specific configuration; defaults to {}. |
Response 201 · Action
Action definition synchronized.
| Field | Type | Required | Description |
|---|---|---|---|
| data.id | uuid | Yes | Action UUID. |
| data.identifier | string | Yes | Stable action identifier. |
| data.display_name | string | Yes | Human-readable label. |
| data.description | string | null | No | Developer-facing description. |
| data.payload_schema | object | Yes | Declared JSON payload schema. |
| data.configuration | object | Yes | Action configuration. |
| data.inserted_at | date-time | Yes | Creation timestamp. |
| data.updated_at | date-time | Yes | Last update timestamp. |
Error responses use the shared error envelope.
/actions/:identifier
Get one action definition.
Request and response schemas
Path parameters
| Field | Type | Required | Description |
|---|---|---|---|
| identifier | string | Yes | Action UUID or stable identifier. |
Request body
No JSON request body.
Response 200 · Action
Action definition returned.
| Field | Type | Required | Description |
|---|---|---|---|
| data.id | uuid | Yes | Action UUID. |
| data.identifier | string | Yes | Stable action identifier. |
| data.display_name | string | Yes | Human-readable label. |
| data.description | string | null | No | Developer-facing description. |
| data.payload_schema | object | Yes | Declared JSON payload schema. |
| data.configuration | object | Yes | Action configuration. |
| data.inserted_at | date-time | Yes | Creation timestamp. |
| data.updated_at | date-time | Yes | Last update timestamp. |
Error responses use the shared error envelope.
/schedules/preview
Preview recurrence occurrences without creating a schedule.
Request and response schemas
Request body · SchedulePreviewInput
| Field | Type | Required | Description |
|---|---|---|---|
| recurrence | object | Yes | Recurrence definition. |
| recurrence.frequency | once | daily | weekly | monthly | Yes | Recurrence frequency. |
| recurrence.timezone | string | Yes | IANA timezone. |
| recurrence.interval | integer ≥ 1 | No | Frequency interval. |
| recurrence.date | date | No | Required for once schedules. |
| recurrence.local_time | HH:MM | No | Local wall-clock execution time. |
| recurrence.weekdays | Weekday[] | No | Required by weekly schedules. |
| recurrence.monthly_mode | string | No | Monthly selection mode. |
| recurrence.day_of_month | integer 1..31 | No | Used by day_of_month mode. |
| recurrence.starts_at | date-time | No | Optional recurrence start. |
| recurrence.ends | object | No | never, on_date, or after_occurrences rule. |
| count | integer 1..10 | No | Occurrences to return; defaults to 3. |
| from | date-time | No | RFC 3339 preview starting point. |
Response 200 · SchedulePreview
Occurrence preview returned.
| Field | Type | Required | Description |
|---|---|---|---|
| data.summary | string | Yes | Human-readable recurrence summary. |
| data.occurrences | Occurrence[] | Yes | Computed occurrence details. |
| data.occurrences[].utc | date-time | Yes | UTC occurrence timestamp. |
| data.occurrences[].local | date-time | Yes | Zoned local timestamp. |
| data.occurrences[].date | date | Yes | Local calendar date. |
| data.occurrences[].time | HH:MM | Yes | Local wall-clock time. |
| data.occurrences[].timezone | string | Yes | IANA timezone. |
| data.occurrences[].timezone_abbreviation | string | Yes | Timezone abbreviation at this occurrence. |
| data.occurrences[].label | string | Yes | Human-readable occurrence label. |
Error responses use the shared error envelope.
/schedules
List schedules visible to this tenant scope.
Request and response schemas
Query parameters
| Field | Type | Required | Description |
|---|---|---|---|
| limit | integer 1..100 | No | Page size; defaults to 25. |
| cursor | string | No | Opaque next_cursor returned by the previous page. |
| external_organization_id | string | No | Exact organization identifier. |
| external_user_id | string | No | Exact owner identifier. |
| action | string | No | Stable action identifier. |
| action_id | uuid | No | Internal action UUID. |
| status | active | paused | deleted | No | Exact lifecycle status. |
Request body
No JSON request body.
Response 200 · SchedulePage
Schedule page returned.
| Field | Type | Required | Description |
|---|---|---|---|
| data[].id | uuid | Yes | Schedule UUID. |
| data[].status | active | paused | deleted | Yes | Current lifecycle state. |
| data[].external_user_id | string | Yes | Owner identifier. |
| data[].external_organization_id | string | null | Yes | Enforced organization scope. |
| data[].action.identifier | string | Yes | Stable action identifier. |
| data[].action.display_name | string | Yes | Action label. |
| data[].payload | object | Yes | Action payload snapshot. |
| data[].recurrence | object | Yes | Normalized recurrence definition. |
| data[].timezone | string | Yes | IANA timezone. |
| data[].start_at | date-time | null | No | First eligible execution time. |
| data[].end_condition | object | null | No | Normalized end rule. |
| data[].overlap_policy | allow | skip | Yes | Concurrent-run policy. |
| data[].misfire_policy | skip | run_once | catch_up | Yes | Missed-run policy. |
| data[].next_run_at | date-time | null | No | Next planned occurrence. |
| data[].last_run_at | date-time | null | No | Most recent occurrence. |
| data[].revision | integer | Yes | Configuration revision. |
| data[].inserted_at | date-time | Yes | Creation timestamp. |
| data[].updated_at | date-time | Yes | Last update timestamp. |
| meta.next_cursor | string | null | Yes | Opaque cursor for the next page. |
| meta.has_more | boolean | Yes | Whether another page is available. |
Error responses use the shared error envelope.
/schedules
Create a durable schedule.
Request and response schemas
Request headers
| Field | Type | Required | Description |
|---|---|---|---|
| Idempotency-Key | string ≤ 255 | No | Stable retry key. Reuse only with an identical request body. |
Request body · ScheduleInput
| Field | Type | Required | Description |
|---|---|---|---|
| action | string | Yes | Stable declared action identifier. |
| external_user_id | string | No | Required for unscoped administrator calls; protected user scope injects and overrides it. |
| external_organization_id | string | No | Required for unscoped administrator calls; protected organization scope injects and overrides it. |
| payload | object | No | Action payload snapshot; defaults to {}. |
| recurrence | object | Yes | Recurrence definition. |
| recurrence.frequency | once | daily | weekly | monthly | Yes | Recurrence frequency. |
| recurrence.timezone | string | Yes | IANA timezone. |
| recurrence.interval | integer ≥ 1 | No | Frequency interval. |
| recurrence.date | date | No | Required for once schedules. |
| recurrence.local_time | HH:MM | No | Local wall-clock execution time. |
| recurrence.weekdays | Weekday[] | No | Required by weekly schedules. |
| recurrence.monthly_mode | string | No | Monthly selection mode. |
| recurrence.day_of_month | integer 1..31 | No | Used by day_of_month mode. |
| recurrence.starts_at | date-time | No | Optional recurrence start. |
| recurrence.ends | object | No | never, on_date, or after_occurrences rule. |
| timezone | string | Yes | IANA timezone; must agree with recurrence.timezone. |
| overlap_policy | allow | skip | No | Concurrent-run policy; defaults to skip. |
| misfire_policy | skip | run_once | catch_up | No | Missed-run policy; defaults to run_once. |
Response 201 · Schedule
Schedule created.
| Field | Type | Required | Description |
|---|---|---|---|
| data.id | uuid | Yes | Schedule UUID. |
| data.status | active | paused | deleted | Yes | Current lifecycle state. |
| data.external_user_id | string | Yes | Owner identifier. |
| data.external_organization_id | string | null | Yes | Enforced organization scope. |
| data.action.identifier | string | Yes | Stable action identifier. |
| data.action.display_name | string | Yes | Action label. |
| data.payload | object | Yes | Action payload snapshot. |
| data.recurrence | object | Yes | Normalized recurrence definition. |
| data.timezone | string | Yes | IANA timezone. |
| data.start_at | date-time | null | No | First eligible execution time. |
| data.end_condition | object | null | No | Normalized end rule. |
| data.overlap_policy | allow | skip | Yes | Concurrent-run policy. |
| data.misfire_policy | skip | run_once | catch_up | Yes | Missed-run policy. |
| data.next_run_at | date-time | null | No | Next planned occurrence. |
| data.last_run_at | date-time | null | No | Most recent occurrence. |
| data.revision | integer | Yes | Configuration revision. |
| data.inserted_at | date-time | Yes | Creation timestamp. |
| data.updated_at | date-time | Yes | Last update timestamp. |
Error responses use the shared error envelope.
/schedules/:id
Get one schedule.
Request and response schemas
Path parameters
| Field | Type | Required | Description |
|---|---|---|---|
| id | uuid | Yes | Schedule UUID. |
Request body
No JSON request body.
Response 200 · Schedule
Schedule returned.
| Field | Type | Required | Description |
|---|---|---|---|
| data.id | uuid | Yes | Schedule UUID. |
| data.status | active | paused | deleted | Yes | Current lifecycle state. |
| data.external_user_id | string | Yes | Owner identifier. |
| data.external_organization_id | string | null | Yes | Enforced organization scope. |
| data.action.identifier | string | Yes | Stable action identifier. |
| data.action.display_name | string | Yes | Action label. |
| data.payload | object | Yes | Action payload snapshot. |
| data.recurrence | object | Yes | Normalized recurrence definition. |
| data.timezone | string | Yes | IANA timezone. |
| data.start_at | date-time | null | No | First eligible execution time. |
| data.end_condition | object | null | No | Normalized end rule. |
| data.overlap_policy | allow | skip | Yes | Concurrent-run policy. |
| data.misfire_policy | skip | run_once | catch_up | Yes | Missed-run policy. |
| data.next_run_at | date-time | null | No | Next planned occurrence. |
| data.last_run_at | date-time | null | No | Most recent occurrence. |
| data.revision | integer | Yes | Configuration revision. |
| data.inserted_at | date-time | Yes | Creation timestamp. |
| data.updated_at | date-time | Yes | Last update timestamp. |
Error responses use the shared error envelope.
/schedules/:id
Partially update schedule configuration.
Request and response schemas
Path parameters
| Field | Type | Required | Description |
|---|---|---|---|
| id | uuid | Yes | Schedule UUID. |
Request body · ScheduleUpdateInput
| Field | Type | Required | Description |
|---|---|---|---|
| action | string | No | Replacement declared action identifier. |
| payload | object | No | Replacement action payload. |
| external_user_id | string | No | Replacement owner for unscoped project-administrator calls; protected user scope overrides it. |
| external_organization_id | string | null | No | Replacement scope for unscoped project-administrator calls; protected organization scope overrides it. |
| recurrence | object | No | Recurrence definition. |
| recurrence.frequency | once | daily | weekly | monthly | No | Recurrence frequency. |
| recurrence.timezone | string | No | IANA timezone. |
| recurrence.interval | integer ≥ 1 | No | Frequency interval. |
| recurrence.date | date | No | Required for once schedules. |
| recurrence.local_time | HH:MM | No | Local wall-clock execution time. |
| recurrence.weekdays | Weekday[] | No | Required by weekly schedules. |
| recurrence.monthly_mode | string | No | Monthly selection mode. |
| recurrence.day_of_month | integer 1..31 | No | Used by day_of_month mode. |
| recurrence.starts_at | date-time | No | Optional recurrence start. |
| recurrence.ends | object | No | never, on_date, or after_occurrences rule. |
| timezone | string | No | Replacement IANA timezone. |
| overlap_policy | allow | skip | No | Replacement overlap policy. |
| misfire_policy | skip | run_once | catch_up | No | Replacement misfire policy. |
Response 200 · Schedule
Updated schedule returned.
| Field | Type | Required | Description |
|---|---|---|---|
| data.id | uuid | Yes | Schedule UUID. |
| data.status | active | paused | deleted | Yes | Current lifecycle state. |
| data.external_user_id | string | Yes | Owner identifier. |
| data.external_organization_id | string | null | Yes | Enforced organization scope. |
| data.action.identifier | string | Yes | Stable action identifier. |
| data.action.display_name | string | Yes | Action label. |
| data.payload | object | Yes | Action payload snapshot. |
| data.recurrence | object | Yes | Normalized recurrence definition. |
| data.timezone | string | Yes | IANA timezone. |
| data.start_at | date-time | null | No | First eligible execution time. |
| data.end_condition | object | null | No | Normalized end rule. |
| data.overlap_policy | allow | skip | Yes | Concurrent-run policy. |
| data.misfire_policy | skip | run_once | catch_up | Yes | Missed-run policy. |
| data.next_run_at | date-time | null | No | Next planned occurrence. |
| data.last_run_at | date-time | null | No | Most recent occurrence. |
| data.revision | integer | Yes | Configuration revision. |
| data.inserted_at | date-time | Yes | Creation timestamp. |
| data.updated_at | date-time | Yes | Last update timestamp. |
Error responses use the shared error envelope.
/schedules/:id
Stop future work and mark the schedule deleted.
Request and response schemas
Path parameters
| Field | Type | Required | Description |
|---|---|---|---|
| id | uuid | Yes | Schedule UUID. |
Request body
No JSON request body.
Response 200 · Schedule
Deleted schedule returned.
| Field | Type | Required | Description |
|---|---|---|---|
| data.id | uuid | Yes | Schedule UUID. |
| data.status | active | paused | deleted | Yes | Current lifecycle state. |
| data.external_user_id | string | Yes | Owner identifier. |
| data.external_organization_id | string | null | Yes | Enforced organization scope. |
| data.action.identifier | string | Yes | Stable action identifier. |
| data.action.display_name | string | Yes | Action label. |
| data.payload | object | Yes | Action payload snapshot. |
| data.recurrence | object | Yes | Normalized recurrence definition. |
| data.timezone | string | Yes | IANA timezone. |
| data.start_at | date-time | null | No | First eligible execution time. |
| data.end_condition | object | null | No | Normalized end rule. |
| data.overlap_policy | allow | skip | Yes | Concurrent-run policy. |
| data.misfire_policy | skip | run_once | catch_up | Yes | Missed-run policy. |
| data.next_run_at | date-time | null | No | Next planned occurrence. |
| data.last_run_at | date-time | null | No | Most recent occurrence. |
| data.revision | integer | Yes | Configuration revision. |
| data.inserted_at | date-time | Yes | Creation timestamp. |
| data.updated_at | date-time | Yes | Last update timestamp. |
Error responses use the shared error envelope.
/schedules/:id/pause
Pause future execution.
Request and response schemas
Path parameters
| Field | Type | Required | Description |
|---|---|---|---|
| id | uuid | Yes | Schedule UUID. |
Request body
No JSON request body.
Response 200 · Schedule
Paused schedule returned.
| Field | Type | Required | Description |
|---|---|---|---|
| data.id | uuid | Yes | Schedule UUID. |
| data.status | active | paused | deleted | Yes | Current lifecycle state. |
| data.external_user_id | string | Yes | Owner identifier. |
| data.external_organization_id | string | null | Yes | Enforced organization scope. |
| data.action.identifier | string | Yes | Stable action identifier. |
| data.action.display_name | string | Yes | Action label. |
| data.payload | object | Yes | Action payload snapshot. |
| data.recurrence | object | Yes | Normalized recurrence definition. |
| data.timezone | string | Yes | IANA timezone. |
| data.start_at | date-time | null | No | First eligible execution time. |
| data.end_condition | object | null | No | Normalized end rule. |
| data.overlap_policy | allow | skip | Yes | Concurrent-run policy. |
| data.misfire_policy | skip | run_once | catch_up | Yes | Missed-run policy. |
| data.next_run_at | date-time | null | No | Next planned occurrence. |
| data.last_run_at | date-time | null | No | Most recent occurrence. |
| data.revision | integer | Yes | Configuration revision. |
| data.inserted_at | date-time | Yes | Creation timestamp. |
| data.updated_at | date-time | Yes | Last update timestamp. |
Error responses use the shared error envelope.
/schedules/:id/resume
Resume execution and compute the next occurrence.
Request and response schemas
Path parameters
| Field | Type | Required | Description |
|---|---|---|---|
| id | uuid | Yes | Schedule UUID. |
Request body
No JSON request body.
Response 200 · Schedule
Resumed schedule returned.
| Field | Type | Required | Description |
|---|---|---|---|
| data.id | uuid | Yes | Schedule UUID. |
| data.status | active | paused | deleted | Yes | Current lifecycle state. |
| data.external_user_id | string | Yes | Owner identifier. |
| data.external_organization_id | string | null | Yes | Enforced organization scope. |
| data.action.identifier | string | Yes | Stable action identifier. |
| data.action.display_name | string | Yes | Action label. |
| data.payload | object | Yes | Action payload snapshot. |
| data.recurrence | object | Yes | Normalized recurrence definition. |
| data.timezone | string | Yes | IANA timezone. |
| data.start_at | date-time | null | No | First eligible execution time. |
| data.end_condition | object | null | No | Normalized end rule. |
| data.overlap_policy | allow | skip | Yes | Concurrent-run policy. |
| data.misfire_policy | skip | run_once | catch_up | Yes | Missed-run policy. |
| data.next_run_at | date-time | null | No | Next planned occurrence. |
| data.last_run_at | date-time | null | No | Most recent occurrence. |
| data.revision | integer | Yes | Configuration revision. |
| data.inserted_at | date-time | Yes | Creation timestamp. |
| data.updated_at | date-time | Yes | Last update timestamp. |
Error responses use the shared error envelope.
/schedules/:id/runs
List runs for one schedule.
Request and response schemas
Path parameters
| Field | Type | Required | Description |
|---|---|---|---|
| id | uuid | Yes | Schedule UUID. |
Query parameters
| Field | Type | Required | Description |
|---|---|---|---|
| limit | integer 1..100 | No | Page size; defaults to 25. |
| cursor | string | No | Opaque next_cursor returned by the previous page. |
Request body
No JSON request body.
Response 200 · RunPage
Run page returned.
| Field | Type | Required | Description |
|---|---|---|---|
| data[].id | uuid | Yes | Run UUID. |
| data[].schedule_id | uuid | Yes | Owning schedule UUID. |
| data[].external_organization_id | string | null | Yes | Enforced organization scope. |
| data[].external_user_id | string | Yes | Schedule owner. |
| data[].action | ActionSummary | Yes | Action identifier and label. |
| data[].status | RunStatus | Yes | Current delivery state. |
| data[].nominal_at | date-time | Yes | Recurrence occurrence time. |
| data[].scheduled_at | date-time | Yes | Queue scheduling time. |
| data[].started_at | date-time | null | No | First attempt start. |
| data[].completed_at | date-time | null | No | Terminal completion time. |
| data[].attempt_count | integer | Yes | Number of delivery attempts. |
| data[].payload_snapshot | object | Yes | Immutable delivered payload. |
| data[].error | string | null | No | Latest failure detail. |
| data[].response_code | integer | null | No | Latest HTTP response status. |
| data[].schedule_revision | integer | Yes | Schedule revision used for this run. |
| data[].inserted_at | date-time | Yes | Creation timestamp. |
| data[].updated_at | date-time | Yes | Last update timestamp. |
| meta.next_cursor | string | null | Yes | Opaque cursor for the next page. |
| meta.has_more | boolean | Yes | Whether another page is available. |
Error responses use the shared error envelope.
/schedules/:id/events
List append-only schedule lifecycle events.
Request and response schemas
Path parameters
| Field | Type | Required | Description |
|---|---|---|---|
| id | uuid | Yes | Schedule UUID. |
Query parameters
| Field | Type | Required | Description |
|---|---|---|---|
| limit | integer 1..100 | No | Page size; defaults to 25. |
| cursor | string | No | Opaque next_cursor returned by the previous page. |
Request body
No JSON request body.
Response 200 · AuditEventPage
Schedule event page returned.
| Field | Type | Required | Description |
|---|---|---|---|
| data[].id | uuid | Yes | Audit event UUID. |
| data[].external_organization_id | string | null | Yes | Enforced organization scope. |
| data[].component | string | Yes | Owning component; manual events use custom. |
| data[].type | string | Yes | Stable event type. |
| data[].actor_id | string | null | No | Actor identifier. |
| data[].subject_type | string | null | No | Subject type. |
| data[].subject_id | string | null | No | Subject identifier. |
| data[].source | system | manual | Yes | Event source. |
| data[].visibility | project | participants | restricted | Yes | Read visibility. |
| data[].data | object | Yes | Event data. |
| data[].tombstoned_at | date-time | null | No | When PII fields were erased. |
| data[].tombstone_reason | AuditTombstoneReason | null | No | Reason for erasure. |
| data[].tombstone_event_id | uuid | null | No | Appended tombstone record UUID. |
| data[].occurred_at | date-time | Yes | Domain occurrence timestamp. |
| data[].inserted_at | date-time | Yes | Persistence timestamp. |
| meta.next_cursor | string | null | Yes | Opaque cursor for the next page. |
| meta.has_more | boolean | Yes | Whether another page is available. |
Error responses use the shared error envelope.
/runs
List and filter schedule runs.
Request and response schemas
Query parameters
| Field | Type | Required | Description |
|---|---|---|---|
| limit | integer 1..100 | No | Page size; defaults to 25. |
| cursor | string | No | Opaque next_cursor returned by the previous page. |
| schedule_id | uuid | No | Exact schedule UUID. |
| external_organization_id | string | No | Exact organization identifier. |
| external_user_id | string | No | Exact schedule owner. |
| action | string | No | Stable action identifier. |
| status | RunStatus | No | Exact run lifecycle status. |
| search | string | No | Free-text run search. |
Request body
No JSON request body.
Response 200 · RunPage
Run page returned.
| Field | Type | Required | Description |
|---|---|---|---|
| data[].id | uuid | Yes | Run UUID. |
| data[].schedule_id | uuid | Yes | Owning schedule UUID. |
| data[].external_organization_id | string | null | Yes | Enforced organization scope. |
| data[].external_user_id | string | Yes | Schedule owner. |
| data[].action | ActionSummary | Yes | Action identifier and label. |
| data[].status | RunStatus | Yes | Current delivery state. |
| data[].nominal_at | date-time | Yes | Recurrence occurrence time. |
| data[].scheduled_at | date-time | Yes | Queue scheduling time. |
| data[].started_at | date-time | null | No | First attempt start. |
| data[].completed_at | date-time | null | No | Terminal completion time. |
| data[].attempt_count | integer | Yes | Number of delivery attempts. |
| data[].payload_snapshot | object | Yes | Immutable delivered payload. |
| data[].error | string | null | No | Latest failure detail. |
| data[].response_code | integer | null | No | Latest HTTP response status. |
| data[].schedule_revision | integer | Yes | Schedule revision used for this run. |
| data[].inserted_at | date-time | Yes | Creation timestamp. |
| data[].updated_at | date-time | Yes | Last update timestamp. |
| meta.next_cursor | string | null | Yes | Opaque cursor for the next page. |
| meta.has_more | boolean | Yes | Whether another page is available. |
Error responses use the shared error envelope.
/runs/:id
Get one run.
Request and response schemas
Path parameters
| Field | Type | Required | Description |
|---|---|---|---|
| id | uuid | Yes | Run UUID. |
Request body
No JSON request body.
Response 200 · Run
Run returned.
| Field | Type | Required | Description |
|---|---|---|---|
| data.id | uuid | Yes | Run UUID. |
| data.schedule_id | uuid | Yes | Owning schedule UUID. |
| data.external_organization_id | string | null | Yes | Enforced organization scope. |
| data.external_user_id | string | Yes | Schedule owner. |
| data.action | ActionSummary | Yes | Action identifier and label. |
| data.status | RunStatus | Yes | Current delivery state. |
| data.nominal_at | date-time | Yes | Recurrence occurrence time. |
| data.scheduled_at | date-time | Yes | Queue scheduling time. |
| data.started_at | date-time | null | No | First attempt start. |
| data.completed_at | date-time | null | No | Terminal completion time. |
| data.attempt_count | integer | Yes | Number of delivery attempts. |
| data.payload_snapshot | object | Yes | Immutable delivered payload. |
| data.error | string | null | No | Latest failure detail. |
| data.response_code | integer | null | No | Latest HTTP response status. |
| data.schedule_revision | integer | Yes | Schedule revision used for this run. |
| data.inserted_at | date-time | Yes | Creation timestamp. |
| data.updated_at | date-time | Yes | Last update timestamp. |
Error responses use the shared error envelope.
Approvals and policies
/approvals/check
Check the latest approval state for a resource and requester.
Request and response schemas
Request body · ApprovalCheckInput
| Field | Type | Required | Description |
|---|---|---|---|
| resource_type | string | Yes | Application resource type. |
| resource_id | string | Yes | Application resource identifier. |
| action | string | Yes | Protected action name. |
| external_organization_id | string | No | Required for unscoped administrator calls; protected organization scope injects and overrides it. |
| requester_id | string | No | Required unless protected user scope supplies and overrides it. |
Response 200 · ApprovalCheck
Approval state returned.
| Field | Type | Required | Description |
|---|---|---|---|
| data.approved | boolean | Yes | Whether the latest matching request is approved. |
| data.status | ApprovalStatus | none | Yes | Latest matching lifecycle state. |
| data.approval_id | uuid | null | No | Latest matching request UUID. |
Error responses use the shared error envelope.
/approvals
List approval requests.
Request and response schemas
Query parameters
| Field | Type | Required | Description |
|---|---|---|---|
| limit | integer 1..100 | No | Page size; defaults to 25. |
| cursor | string | No | Opaque next_cursor returned by the previous page. |
| external_organization_id | string | No | Exact organization identifier. |
| resource_id | string | No | Exact resource identifier. |
| requester_id | string | No | Exact requester identifier. |
| approver_id | string | No | Requests visible to this approver. |
| status | ApprovalStatus | No | Exact lifecycle status. |
Request body
No JSON request body.
Response 200 · ApprovalPage
Approval page returned.
| Field | Type | Required | Description |
|---|---|---|---|
| data[].id | uuid | Yes | Approval request UUID. |
| data[].project_id | uuid | Yes | Owning project UUID. |
| data[].external_organization_id | string | null | Yes | Enforced organization scope. |
| data[].resource_type | string | Yes | Application resource type. |
| data[].resource_id | string | Yes | Application resource identifier. |
| data[].action | string | Yes | Protected action. |
| data[].requester_id | string | Yes | Requester identifier. |
| data[].approver_id | string | null | No | Resolving approver when applicable. |
| data[].status | ApprovalStatus | Yes | Current lifecycle state. |
| data[].title | string | null | No | Request title. |
| data[].description | string | null | No | Request context. |
| data[].metadata | object | Yes | Application metadata. |
| data[].revision | integer | Yes | Content revision. |
| data[].policy_id | uuid | null | No | Resolved policy UUID. |
| data[].policy_snapshot | object | Yes | Immutable policy used for this request. |
| data[].decisions | Decision[] | Yes | Append-only actor decisions. |
| data[].events | LifecycleEvent[] | Yes | Request lifecycle history. |
| data[].expires_at | date-time | null | No | Expiry timestamp. |
| data[].resolved_at | date-time | null | No | Resolution timestamp. |
| data[].cancelled_at | date-time | null | No | Cancellation timestamp. |
| data[].revoked_at | date-time | null | No | Revocation timestamp. |
| data[].inserted_at | date-time | Yes | Creation timestamp. |
| data[].updated_at | date-time | Yes | Last update timestamp. |
| meta.next_cursor | string | null | Yes | Opaque cursor for the next page. |
| meta.has_more | boolean | Yes | Whether another page is available. |
Error responses use the shared error envelope.
/approvals
Create a durable approval request.
Request and response schemas
Request headers
| Field | Type | Required | Description |
|---|---|---|---|
| Idempotency-Key | string ≤ 255 | No | Stable retry key. Reuse only with an identical request body. |
Request body · ApprovalRequestInput
| Field | Type | Required | Description |
|---|---|---|---|
| resource_type | string | Yes | Application resource type. |
| resource_id | string | Yes | Application resource identifier. |
| action | string | Yes | Protected action name. |
| external_organization_id | string | No | Required for unscoped administrator calls; protected organization scope injects and overrides it. |
| requester_id | string | No | Required unless protected user scope supplies and overrides it. |
| policy_id | uuid | No | Explicit policy; otherwise matching policy resolution runs. |
| title | string | No | Human-readable request title. |
| description | string | No | Request context. |
| metadata | object | No | Application metadata; defaults to {}. |
| expires_at | date-time | No | Optional RFC 3339 expiry. |
Response 201 · Approval
Approval request created.
| Field | Type | Required | Description |
|---|---|---|---|
| data.id | uuid | Yes | Approval request UUID. |
| data.project_id | uuid | Yes | Owning project UUID. |
| data.external_organization_id | string | null | Yes | Enforced organization scope. |
| data.resource_type | string | Yes | Application resource type. |
| data.resource_id | string | Yes | Application resource identifier. |
| data.action | string | Yes | Protected action. |
| data.requester_id | string | Yes | Requester identifier. |
| data.approver_id | string | null | No | Resolving approver when applicable. |
| data.status | ApprovalStatus | Yes | Current lifecycle state. |
| data.title | string | null | No | Request title. |
| data.description | string | null | No | Request context. |
| data.metadata | object | Yes | Application metadata. |
| data.revision | integer | Yes | Content revision. |
| data.policy_id | uuid | null | No | Resolved policy UUID. |
| data.policy_snapshot | object | Yes | Immutable policy used for this request. |
| data.decisions | Decision[] | Yes | Append-only actor decisions. |
| data.events | LifecycleEvent[] | Yes | Request lifecycle history. |
| data.expires_at | date-time | null | No | Expiry timestamp. |
| data.resolved_at | date-time | null | No | Resolution timestamp. |
| data.cancelled_at | date-time | null | No | Cancellation timestamp. |
| data.revoked_at | date-time | null | No | Revocation timestamp. |
| data.inserted_at | date-time | Yes | Creation timestamp. |
| data.updated_at | date-time | Yes | Last update timestamp. |
Error responses use the shared error envelope.
/approvals/:id
Get a request with decisions and lifecycle events.
Request and response schemas
Path parameters
| Field | Type | Required | Description |
|---|---|---|---|
| id | uuid | Yes | Approval request UUID. |
Request body
No JSON request body.
Response 200 · Approval
Approval request returned.
| Field | Type | Required | Description |
|---|---|---|---|
| data.id | uuid | Yes | Approval request UUID. |
| data.project_id | uuid | Yes | Owning project UUID. |
| data.external_organization_id | string | null | Yes | Enforced organization scope. |
| data.resource_type | string | Yes | Application resource type. |
| data.resource_id | string | Yes | Application resource identifier. |
| data.action | string | Yes | Protected action. |
| data.requester_id | string | Yes | Requester identifier. |
| data.approver_id | string | null | No | Resolving approver when applicable. |
| data.status | ApprovalStatus | Yes | Current lifecycle state. |
| data.title | string | null | No | Request title. |
| data.description | string | null | No | Request context. |
| data.metadata | object | Yes | Application metadata. |
| data.revision | integer | Yes | Content revision. |
| data.policy_id | uuid | null | No | Resolved policy UUID. |
| data.policy_snapshot | object | Yes | Immutable policy used for this request. |
| data.decisions | Decision[] | Yes | Append-only actor decisions. |
| data.events | LifecycleEvent[] | Yes | Request lifecycle history. |
| data.expires_at | date-time | null | No | Expiry timestamp. |
| data.resolved_at | date-time | null | No | Resolution timestamp. |
| data.cancelled_at | date-time | null | No | Cancellation timestamp. |
| data.revoked_at | date-time | null | No | Revocation timestamp. |
| data.inserted_at | date-time | Yes | Creation timestamp. |
| data.updated_at | date-time | Yes | Last update timestamp. |
Error responses use the shared error envelope.
/approvals/:id
Update editable content while the request is pending.
Request and response schemas
Path parameters
| Field | Type | Required | Description |
|---|---|---|---|
| id | uuid | Yes | Approval request UUID. |
Request body · ApprovalUpdateInput
| Field | Type | Required | Description |
|---|---|---|---|
| title | string | null | No | Replacement title. |
| description | string | null | No | Replacement description. |
| metadata | object | No | Replacement metadata. |
| expires_at | date-time | null | No | Replacement expiry. |
Response 200 · Approval
Updated request returned.
| Field | Type | Required | Description |
|---|---|---|---|
| data.id | uuid | Yes | Approval request UUID. |
| data.project_id | uuid | Yes | Owning project UUID. |
| data.external_organization_id | string | null | Yes | Enforced organization scope. |
| data.resource_type | string | Yes | Application resource type. |
| data.resource_id | string | Yes | Application resource identifier. |
| data.action | string | Yes | Protected action. |
| data.requester_id | string | Yes | Requester identifier. |
| data.approver_id | string | null | No | Resolving approver when applicable. |
| data.status | ApprovalStatus | Yes | Current lifecycle state. |
| data.title | string | null | No | Request title. |
| data.description | string | null | No | Request context. |
| data.metadata | object | Yes | Application metadata. |
| data.revision | integer | Yes | Content revision. |
| data.policy_id | uuid | null | No | Resolved policy UUID. |
| data.policy_snapshot | object | Yes | Immutable policy used for this request. |
| data.decisions | Decision[] | Yes | Append-only actor decisions. |
| data.events | LifecycleEvent[] | Yes | Request lifecycle history. |
| data.expires_at | date-time | null | No | Expiry timestamp. |
| data.resolved_at | date-time | null | No | Resolution timestamp. |
| data.cancelled_at | date-time | null | No | Cancellation timestamp. |
| data.revoked_at | date-time | null | No | Revocation timestamp. |
| data.inserted_at | date-time | Yes | Creation timestamp. |
| data.updated_at | date-time | Yes | Last update timestamp. |
Error responses use the shared error envelope.
/approvals/:id
Cancel and remove a request through its lifecycle.
Request and response schemas
Path parameters
| Field | Type | Required | Description |
|---|---|---|---|
| id | uuid | Yes | Approval request UUID. |
Request body
No JSON request body.
Response 200 · Approval
Cancelled request returned.
| Field | Type | Required | Description |
|---|---|---|---|
| data.id | uuid | Yes | Approval request UUID. |
| data.project_id | uuid | Yes | Owning project UUID. |
| data.external_organization_id | string | null | Yes | Enforced organization scope. |
| data.resource_type | string | Yes | Application resource type. |
| data.resource_id | string | Yes | Application resource identifier. |
| data.action | string | Yes | Protected action. |
| data.requester_id | string | Yes | Requester identifier. |
| data.approver_id | string | null | No | Resolving approver when applicable. |
| data.status | ApprovalStatus | Yes | Current lifecycle state. |
| data.title | string | null | No | Request title. |
| data.description | string | null | No | Request context. |
| data.metadata | object | Yes | Application metadata. |
| data.revision | integer | Yes | Content revision. |
| data.policy_id | uuid | null | No | Resolved policy UUID. |
| data.policy_snapshot | object | Yes | Immutable policy used for this request. |
| data.decisions | Decision[] | Yes | Append-only actor decisions. |
| data.events | LifecycleEvent[] | Yes | Request lifecycle history. |
| data.expires_at | date-time | null | No | Expiry timestamp. |
| data.resolved_at | date-time | null | No | Resolution timestamp. |
| data.cancelled_at | date-time | null | No | Cancellation timestamp. |
| data.revoked_at | date-time | null | No | Revocation timestamp. |
| data.inserted_at | date-time | Yes | Creation timestamp. |
| data.updated_at | date-time | Yes | Last update timestamp. |
Error responses use the shared error envelope.
/approvals/:id/decisions
Record an approver decision.
Request and response schemas
Path parameters
| Field | Type | Required | Description |
|---|---|---|---|
| id | uuid | Yes | Approval request UUID. |
Request headers
| Field | Type | Required | Description |
|---|---|---|---|
| Idempotency-Key | string ≤ 255 | No | Stable retry key. Reuse only with an identical request body. |
Request body · ApprovalDecisionInput
| Field | Type | Required | Description |
|---|---|---|---|
| decision | approved | rejected | Yes | The actor's decision. |
| approver_id | string | No | Required unless protected user scope supplies and overrides it. |
| reason | string | No | Optional decision rationale. |
Response 200 · Approval
Resolved or pending request returned.
| Field | Type | Required | Description |
|---|---|---|---|
| data.id | uuid | Yes | Approval request UUID. |
| data.project_id | uuid | Yes | Owning project UUID. |
| data.external_organization_id | string | null | Yes | Enforced organization scope. |
| data.resource_type | string | Yes | Application resource type. |
| data.resource_id | string | Yes | Application resource identifier. |
| data.action | string | Yes | Protected action. |
| data.requester_id | string | Yes | Requester identifier. |
| data.approver_id | string | null | No | Resolving approver when applicable. |
| data.status | ApprovalStatus | Yes | Current lifecycle state. |
| data.title | string | null | No | Request title. |
| data.description | string | null | No | Request context. |
| data.metadata | object | Yes | Application metadata. |
| data.revision | integer | Yes | Content revision. |
| data.policy_id | uuid | null | No | Resolved policy UUID. |
| data.policy_snapshot | object | Yes | Immutable policy used for this request. |
| data.decisions | Decision[] | Yes | Append-only actor decisions. |
| data.events | LifecycleEvent[] | Yes | Request lifecycle history. |
| data.expires_at | date-time | null | No | Expiry timestamp. |
| data.resolved_at | date-time | null | No | Resolution timestamp. |
| data.cancelled_at | date-time | null | No | Cancellation timestamp. |
| data.revoked_at | date-time | null | No | Revocation timestamp. |
| data.inserted_at | date-time | Yes | Creation timestamp. |
| data.updated_at | date-time | Yes | Last update timestamp. |
Error responses use the shared error envelope.
/approvals/:id/cancel
Cancel a pending request.
Request and response schemas
Path parameters
| Field | Type | Required | Description |
|---|---|---|---|
| id | uuid | Yes | Approval request UUID. |
Request body · LifecycleCommandInput
| Field | Type | Required | Description |
|---|---|---|---|
| actor_id | string | No | Actor; framework proxies inject this value. |
| reason | string | No | Optional cancellation or revocation rationale. |
Response 200 · Approval
Cancelled request returned.
| Field | Type | Required | Description |
|---|---|---|---|
| data.id | uuid | Yes | Approval request UUID. |
| data.project_id | uuid | Yes | Owning project UUID. |
| data.external_organization_id | string | null | Yes | Enforced organization scope. |
| data.resource_type | string | Yes | Application resource type. |
| data.resource_id | string | Yes | Application resource identifier. |
| data.action | string | Yes | Protected action. |
| data.requester_id | string | Yes | Requester identifier. |
| data.approver_id | string | null | No | Resolving approver when applicable. |
| data.status | ApprovalStatus | Yes | Current lifecycle state. |
| data.title | string | null | No | Request title. |
| data.description | string | null | No | Request context. |
| data.metadata | object | Yes | Application metadata. |
| data.revision | integer | Yes | Content revision. |
| data.policy_id | uuid | null | No | Resolved policy UUID. |
| data.policy_snapshot | object | Yes | Immutable policy used for this request. |
| data.decisions | Decision[] | Yes | Append-only actor decisions. |
| data.events | LifecycleEvent[] | Yes | Request lifecycle history. |
| data.expires_at | date-time | null | No | Expiry timestamp. |
| data.resolved_at | date-time | null | No | Resolution timestamp. |
| data.cancelled_at | date-time | null | No | Cancellation timestamp. |
| data.revoked_at | date-time | null | No | Revocation timestamp. |
| data.inserted_at | date-time | Yes | Creation timestamp. |
| data.updated_at | date-time | Yes | Last update timestamp. |
Error responses use the shared error envelope.
/approvals/:id/revoke
Revoke a previously approved request.
Request and response schemas
Path parameters
| Field | Type | Required | Description |
|---|---|---|---|
| id | uuid | Yes | Approval request UUID. |
Request body · LifecycleCommandInput
| Field | Type | Required | Description |
|---|---|---|---|
| actor_id | string | No | Actor; framework proxies inject this value. |
| reason | string | No | Optional cancellation or revocation rationale. |
Response 200 · Approval
Revoked request returned.
| Field | Type | Required | Description |
|---|---|---|---|
| data.id | uuid | Yes | Approval request UUID. |
| data.project_id | uuid | Yes | Owning project UUID. |
| data.external_organization_id | string | null | Yes | Enforced organization scope. |
| data.resource_type | string | Yes | Application resource type. |
| data.resource_id | string | Yes | Application resource identifier. |
| data.action | string | Yes | Protected action. |
| data.requester_id | string | Yes | Requester identifier. |
| data.approver_id | string | null | No | Resolving approver when applicable. |
| data.status | ApprovalStatus | Yes | Current lifecycle state. |
| data.title | string | null | No | Request title. |
| data.description | string | null | No | Request context. |
| data.metadata | object | Yes | Application metadata. |
| data.revision | integer | Yes | Content revision. |
| data.policy_id | uuid | null | No | Resolved policy UUID. |
| data.policy_snapshot | object | Yes | Immutable policy used for this request. |
| data.decisions | Decision[] | Yes | Append-only actor decisions. |
| data.events | LifecycleEvent[] | Yes | Request lifecycle history. |
| data.expires_at | date-time | null | No | Expiry timestamp. |
| data.resolved_at | date-time | null | No | Resolution timestamp. |
| data.cancelled_at | date-time | null | No | Cancellation timestamp. |
| data.revoked_at | date-time | null | No | Revocation timestamp. |
| data.inserted_at | date-time | Yes | Creation timestamp. |
| data.updated_at | date-time | Yes | Last update timestamp. |
Error responses use the shared error envelope.
/approvals/:id/events
List request lifecycle events.
Request and response schemas
Path parameters
| Field | Type | Required | Description |
|---|---|---|---|
| id | uuid | Yes | Approval request UUID. |
Query parameters
| Field | Type | Required | Description |
|---|---|---|---|
| limit | integer 1..100 | No | Page size; defaults to 25. |
| cursor | string | No | Opaque next_cursor returned by the previous page. |
Request body
No JSON request body.
Response 200 · LifecycleEventPage
Approval event page returned.
| Field | Type | Required | Description |
|---|---|---|---|
| data[].id | uuid | Yes | Event UUID. |
| data[].type | string | Yes | Lifecycle event type. |
| data[].actor_id | string | null | No | Actor identifier. |
| data[].data | object | Yes | Event-specific data. |
| data[].inserted_at | date-time | Yes | Persistence timestamp. |
| meta.next_cursor | string | null | Yes | Opaque cursor for the next page. |
| meta.has_more | boolean | Yes | Whether another page is available. |
Error responses use the shared error envelope.
/approval-policies
List project-global and matching organization policies.
Request and response schemas
Query parameters
| Field | Type | Required | Description |
|---|---|---|---|
| limit | integer 1..100 | No | Page size; defaults to 25. |
| cursor | string | No | Opaque next_cursor returned by the previous page. |
| external_organization_id | string | No | Exact organization identifier. |
Request body
No JSON request body.
Response 200 · ApprovalPolicyPage
Policy page returned.
| Field | Type | Required | Description |
|---|---|---|---|
| data[].id | uuid | Yes | Policy UUID. |
| data[].project_id | uuid | Yes | Owning project UUID. |
| data[].external_organization_id | string | null | Yes | Organization scope, or null for a project-global policy. |
| data[].resource_pattern | string | Yes | Resource matcher. |
| data[].allowed_approvers | string[] | Yes | Eligible actors. |
| data[].mode | any | all | quorum | Yes | Aggregation mode. |
| data[].required_approvals | integer | Yes | Required approval count. |
| data[].allow_self_approval | boolean | Yes | Whether requester decisions are allowed. |
| data[].revision | integer | Yes | Policy revision. |
| data[].inserted_at | date-time | Yes | Creation timestamp. |
| data[].updated_at | date-time | Yes | Last update timestamp. |
| meta.next_cursor | string | null | Yes | Opaque cursor for the next page. |
| meta.has_more | boolean | Yes | Whether another page is available. |
Error responses use the shared error envelope.
/approval-policies
Create an any, all, or quorum policy.
Request and response schemas
Request body · ApprovalPolicyInput
| Field | Type | Required | Description |
|---|---|---|---|
| external_organization_id | string | null | No | Organization policy scope. Protected organization scope overrides it; only an unscoped administrator can create a project-global policy. |
| resource_pattern | string | Yes | Resource matcher unique within the project. |
| allowed_approvers | string[] | Yes | Actors eligible to decide. |
| mode | any | all | quorum | Yes | Decision aggregation mode. |
| required_approvals | integer ≥ 1 | Yes | Required approvals, especially for quorum. |
| allow_self_approval | boolean | No | Allow requester decisions; defaults to false. |
Response 201 · ApprovalPolicy
Policy created.
| Field | Type | Required | Description |
|---|---|---|---|
| data.id | uuid | Yes | Policy UUID. |
| data.project_id | uuid | Yes | Owning project UUID. |
| data.external_organization_id | string | null | Yes | Organization scope, or null for a project-global policy. |
| data.resource_pattern | string | Yes | Resource matcher. |
| data.allowed_approvers | string[] | Yes | Eligible actors. |
| data.mode | any | all | quorum | Yes | Aggregation mode. |
| data.required_approvals | integer | Yes | Required approval count. |
| data.allow_self_approval | boolean | Yes | Whether requester decisions are allowed. |
| data.revision | integer | Yes | Policy revision. |
| data.inserted_at | date-time | Yes | Creation timestamp. |
| data.updated_at | date-time | Yes | Last update timestamp. |
Error responses use the shared error envelope.
/approval-policies/:id
Get one policy.
Request and response schemas
Path parameters
| Field | Type | Required | Description |
|---|---|---|---|
| id | uuid | Yes | Approval policy UUID. |
Request body
No JSON request body.
Response 200 · ApprovalPolicy
Policy returned.
| Field | Type | Required | Description |
|---|---|---|---|
| data.id | uuid | Yes | Policy UUID. |
| data.project_id | uuid | Yes | Owning project UUID. |
| data.external_organization_id | string | null | Yes | Organization scope, or null for a project-global policy. |
| data.resource_pattern | string | Yes | Resource matcher. |
| data.allowed_approvers | string[] | Yes | Eligible actors. |
| data.mode | any | all | quorum | Yes | Aggregation mode. |
| data.required_approvals | integer | Yes | Required approval count. |
| data.allow_self_approval | boolean | Yes | Whether requester decisions are allowed. |
| data.revision | integer | Yes | Policy revision. |
| data.inserted_at | date-time | Yes | Creation timestamp. |
| data.updated_at | date-time | Yes | Last update timestamp. |
Error responses use the shared error envelope.
/approval-policies/:id
Update a policy for future requests.
Request and response schemas
Path parameters
| Field | Type | Required | Description |
|---|---|---|---|
| id | uuid | Yes | Approval policy UUID. |
Request body · ApprovalPolicyUpdateInput
| Field | Type | Required | Description |
|---|---|---|---|
| external_organization_id | string | null | No | Organization policy scope. Protected organization scope overrides it; only an unscoped administrator can create a project-global policy. |
| resource_pattern | string | No | Resource matcher unique within the project. |
| allowed_approvers | string[] | No | Actors eligible to decide. |
| mode | any | all | quorum | No | Decision aggregation mode. |
| required_approvals | integer ≥ 1 | No | Required approvals, especially for quorum. |
| allow_self_approval | boolean | No | Allow requester decisions; defaults to false. |
Response 200 · ApprovalPolicy
Updated policy returned.
| Field | Type | Required | Description |
|---|---|---|---|
| data.id | uuid | Yes | Policy UUID. |
| data.project_id | uuid | Yes | Owning project UUID. |
| data.external_organization_id | string | null | Yes | Organization scope, or null for a project-global policy. |
| data.resource_pattern | string | Yes | Resource matcher. |
| data.allowed_approvers | string[] | Yes | Eligible actors. |
| data.mode | any | all | quorum | Yes | Aggregation mode. |
| data.required_approvals | integer | Yes | Required approval count. |
| data.allow_self_approval | boolean | Yes | Whether requester decisions are allowed. |
| data.revision | integer | Yes | Policy revision. |
| data.inserted_at | date-time | Yes | Creation timestamp. |
| data.updated_at | date-time | Yes | Last update timestamp. |
Error responses use the shared error envelope.
/approval-policies/:id
Delete a policy without changing request snapshots.
Request and response schemas
Path parameters
| Field | Type | Required | Description |
|---|---|---|---|
| id | uuid | Yes | Approval policy UUID. |
Request body
No JSON request body.
Response 200 · ApprovalPolicy
Deleted policy returned.
| Field | Type | Required | Description |
|---|---|---|---|
| data.id | uuid | Yes | Policy UUID. |
| data.project_id | uuid | Yes | Owning project UUID. |
| data.external_organization_id | string | null | Yes | Organization scope, or null for a project-global policy. |
| data.resource_pattern | string | Yes | Resource matcher. |
| data.allowed_approvers | string[] | Yes | Eligible actors. |
| data.mode | any | all | quorum | Yes | Aggregation mode. |
| data.required_approvals | integer | Yes | Required approval count. |
| data.allow_self_approval | boolean | Yes | Whether requester decisions are allowed. |
| data.revision | integer | Yes | Policy revision. |
| data.inserted_at | date-time | Yes | Creation timestamp. |
| data.updated_at | date-time | Yes | Last update timestamp. |
Error responses use the shared error envelope.
Audit, Bulk, and sessions
/audit-events
Query visible Audit events.
Request and response schemas
Query parameters
| Field | Type | Required | Description |
|---|---|---|---|
| limit | integer 1..100 | No | Page size; defaults to 25. |
| cursor | string | No | Opaque next_cursor returned by the previous page. |
| external_organization_id | string | No | Exact organization identifier. |
| component | string | No | Exact component key. |
| components | string | No | Comma-separated component keys. |
| type | string | No | Exact event type. |
| type_prefix | string | No | Event type prefix. |
| actor_id | string | No | Exact actor identifier. |
| subject_type | string | No | Exact subject type. |
| subject_id | string | No | Exact subject identifier. |
| viewer_id | string | No | Apply participant/restricted visibility. |
| since | date-time | No | Inclusive RFC 3339 lower bound. |
| until | date-time | No | Inclusive RFC 3339 upper bound. |
Request body
No JSON request body.
Response 200 · AuditEventPage
Audit event page returned.
| Field | Type | Required | Description |
|---|---|---|---|
| data[].id | uuid | Yes | Audit event UUID. |
| data[].external_organization_id | string | null | Yes | Enforced organization scope. |
| data[].component | string | Yes | Owning component; manual events use custom. |
| data[].type | string | Yes | Stable event type. |
| data[].actor_id | string | null | No | Actor identifier. |
| data[].subject_type | string | null | No | Subject type. |
| data[].subject_id | string | null | No | Subject identifier. |
| data[].source | system | manual | Yes | Event source. |
| data[].visibility | project | participants | restricted | Yes | Read visibility. |
| data[].data | object | Yes | Event data. |
| data[].tombstoned_at | date-time | null | No | When PII fields were erased. |
| data[].tombstone_reason | AuditTombstoneReason | null | No | Reason for erasure. |
| data[].tombstone_event_id | uuid | null | No | Appended tombstone record UUID. |
| data[].occurred_at | date-time | Yes | Domain occurrence timestamp. |
| data[].inserted_at | date-time | Yes | Persistence timestamp. |
| meta.next_cursor | string | null | Yes | Opaque cursor for the next page. |
| meta.has_more | boolean | Yes | Whether another page is available. |
Error responses use the shared error envelope.
/audit-events
Create an idempotent manual application event.
Request and response schemas
Request headers
| Field | Type | Required | Description |
|---|---|---|---|
| Idempotency-Key | string ≤ 255 | No | Stable retry key. Reuse only with an identical request body. |
Request body · AuditEventInput
| Field | Type | Required | Description |
|---|---|---|---|
| type | string | Yes | Stable application event type. |
| external_organization_id | string | No | Required for unscoped administrator calls; protected organization scope injects and overrides it. |
| actor_id | string | No | Actor responsible for the event. |
| subject_type | string | No | Application subject type. |
| subject_id | string | No | Application subject identifier. |
| visibility | project | participants | restricted | No | Read visibility; defaults to project. |
| participant_ids | string[] | No | Actors allowed by participant visibility. |
| allowed_viewer_ids | string[] | No | Actors allowed by restricted visibility. |
| data | object | No | Application event data. |
| occurred_at | date-time | No | Original occurrence; defaults to receipt time. |
Response 201 · AuditEvent
Audit event created.
| Field | Type | Required | Description |
|---|---|---|---|
| data.id | uuid | Yes | Audit event UUID. |
| data.external_organization_id | string | null | Yes | Enforced organization scope. |
| data.component | string | Yes | Owning component; manual events use custom. |
| data.type | string | Yes | Stable event type. |
| data.actor_id | string | null | No | Actor identifier. |
| data.subject_type | string | null | No | Subject type. |
| data.subject_id | string | null | No | Subject identifier. |
| data.source | system | manual | Yes | Event source. |
| data.visibility | project | participants | restricted | Yes | Read visibility. |
| data.data | object | Yes | Event data. |
| data.tombstoned_at | date-time | null | No | When PII fields were erased. |
| data.tombstone_reason | AuditTombstoneReason | null | No | Reason for erasure. |
| data.tombstone_event_id | uuid | null | No | Appended tombstone record UUID. |
| data.occurred_at | date-time | Yes | Domain occurrence timestamp. |
| data.inserted_at | date-time | Yes | Persistence timestamp. |
Error responses use the shared error envelope.
/audit-events/:id
Get one visible Audit event.
Request and response schemas
Path parameters
| Field | Type | Required | Description |
|---|---|---|---|
| id | uuid | Yes | Audit event UUID. |
Query parameters
| Field | Type | Required | Description |
|---|---|---|---|
| viewer_id | string | No | Apply participant/restricted visibility. |
Request body
No JSON request body.
Response 200 · AuditEvent
Audit event returned.
| Field | Type | Required | Description |
|---|---|---|---|
| data.id | uuid | Yes | Audit event UUID. |
| data.external_organization_id | string | null | Yes | Enforced organization scope. |
| data.component | string | Yes | Owning component; manual events use custom. |
| data.type | string | Yes | Stable event type. |
| data.actor_id | string | null | No | Actor identifier. |
| data.subject_type | string | null | No | Subject type. |
| data.subject_id | string | null | No | Subject identifier. |
| data.source | system | manual | Yes | Event source. |
| data.visibility | project | participants | restricted | Yes | Read visibility. |
| data.data | object | Yes | Event data. |
| data.tombstoned_at | date-time | null | No | When PII fields were erased. |
| data.tombstone_reason | AuditTombstoneReason | null | No | Reason for erasure. |
| data.tombstone_event_id | uuid | null | No | Appended tombstone record UUID. |
| data.occurred_at | date-time | Yes | Domain occurrence timestamp. |
| data.inserted_at | date-time | Yes | Persistence timestamp. |
Error responses use the shared error envelope.
/audit-events/:id/tombstone
Erase PII from one Audit event.
Request and response schemas
Path parameters
| Field | Type | Required | Description |
|---|---|---|---|
| id | uuid | Yes | Audit event UUID. |
Request body · AuditTombstoneInput
| Field | Type | Required | Description |
|---|---|---|---|
| reason | data_subject_erasure | sensitive_data | customer_request | Yes | Constrained privacy-erasure reason. |
| actor_id | string | No | Optional trusted privacy operator identifier. |
Response 200 · AuditEvent
Tombstoned event returned.
| Field | Type | Required | Description |
|---|---|---|---|
| data.id | uuid | Yes | Audit event UUID. |
| data.external_organization_id | string | null | Yes | Enforced organization scope. |
| data.component | string | Yes | Owning component; manual events use custom. |
| data.type | string | Yes | Stable event type. |
| data.actor_id | string | null | No | Actor identifier. |
| data.subject_type | string | null | No | Subject type. |
| data.subject_id | string | null | No | Subject identifier. |
| data.source | system | manual | Yes | Event source. |
| data.visibility | project | participants | restricted | Yes | Read visibility. |
| data.data | object | Yes | Event data. |
| data.tombstoned_at | date-time | null | No | When PII fields were erased. |
| data.tombstone_reason | AuditTombstoneReason | null | No | Reason for erasure. |
| data.tombstone_event_id | uuid | null | No | Appended tombstone record UUID. |
| data.occurred_at | date-time | Yes | Domain occurrence timestamp. |
| data.inserted_at | date-time | Yes | Persistence timestamp. |
Error responses use the shared error envelope.
/bulk-operations
List durable bulk operations.
Request and response schemas
Query parameters
| Field | Type | Required | Description |
|---|---|---|---|
| limit | integer 1..100 | No | Page size; defaults to 25. |
| cursor | string | No | Opaque next_cursor returned by the previous page. |
| external_organization_id | string | No | Exact organization identifier. |
| status | BulkStatus | No | Exact operation status. |
| action | string | No | Stable action identifier. |
Request body
No JSON request body.
Response 200 · BulkOperationPage
Bulk operation page returned.
| Field | Type | Required | Description |
|---|---|---|---|
| data[].id | uuid | Yes | Operation UUID. |
| data[].project_id | uuid | Yes | Owning project UUID. |
| data[].external_organization_id | string | null | Yes | Enforced organization scope. |
| data[].action | string | Yes | Stable action identifier. |
| data[].status | BulkStatus | Yes | Current operation state. |
| data[].metadata | object | Yes | Operation metadata. |
| data[].chunk_size | integer | Yes | Items per chunk. |
| data[].progress | object | Yes | Item/chunk totals, outcomes, and percentage. |
| data[].started_at | date-time | null | No | Processing start. |
| data[].completed_at | date-time | null | No | Terminal completion. |
| data[].cancelled_at | date-time | null | No | Cancellation timestamp. |
| data[].inserted_at | date-time | Yes | Creation timestamp. |
| data[].updated_at | date-time | Yes | Last update timestamp. |
| meta.next_cursor | string | null | Yes | Opaque cursor for the next page. |
| meta.has_more | boolean | Yes | Whether another page is available. |
Error responses use the shared error envelope.
/bulk-operations
Create a durable chunked operation.
Request and response schemas
Request headers
| Field | Type | Required | Description |
|---|---|---|---|
| Idempotency-Key | string ≤ 255 | No | Stable retry key. Reuse only with an identical request body. |
Request body · BulkOperationInput
| Field | Type | Required | Description |
|---|---|---|---|
| external_organization_id | string | No | Required for unscoped administrator calls; protected organization scope injects and overrides it. |
| action | string | Yes | Stable declared action identifier. |
| items | object[] | Yes | Between 1 and 100,000 item payloads. |
| chunk_size | integer 1..1000 | No | Items per delivery; defaults to 100. |
| metadata | object | No | Operation metadata delivered with each chunk. |
Response 201 · BulkOperation
Bulk operation created.
| Field | Type | Required | Description |
|---|---|---|---|
| data.id | uuid | Yes | Operation UUID. |
| data.project_id | uuid | Yes | Owning project UUID. |
| data.external_organization_id | string | null | Yes | Enforced organization scope. |
| data.action | string | Yes | Stable action identifier. |
| data.status | BulkStatus | Yes | Current operation state. |
| data.metadata | object | Yes | Operation metadata. |
| data.chunk_size | integer | Yes | Items per chunk. |
| data.progress | object | Yes | Item/chunk totals, outcomes, and percentage. |
| data.started_at | date-time | null | No | Processing start. |
| data.completed_at | date-time | null | No | Terminal completion. |
| data.cancelled_at | date-time | null | No | Cancellation timestamp. |
| data.inserted_at | date-time | Yes | Creation timestamp. |
| data.updated_at | date-time | Yes | Last update timestamp. |
Error responses use the shared error envelope.
/bulk-operations/:id
Get operation state and aggregate progress.
Request and response schemas
Path parameters
| Field | Type | Required | Description |
|---|---|---|---|
| id | uuid | Yes | Bulk operation UUID. |
Request body
No JSON request body.
Response 200 · BulkOperation
Bulk operation returned.
| Field | Type | Required | Description |
|---|---|---|---|
| data.id | uuid | Yes | Operation UUID. |
| data.project_id | uuid | Yes | Owning project UUID. |
| data.external_organization_id | string | null | Yes | Enforced organization scope. |
| data.action | string | Yes | Stable action identifier. |
| data.status | BulkStatus | Yes | Current operation state. |
| data.metadata | object | Yes | Operation metadata. |
| data.chunk_size | integer | Yes | Items per chunk. |
| data.progress | object | Yes | Item/chunk totals, outcomes, and percentage. |
| data.started_at | date-time | null | No | Processing start. |
| data.completed_at | date-time | null | No | Terminal completion. |
| data.cancelled_at | date-time | null | No | Cancellation timestamp. |
| data.inserted_at | date-time | Yes | Creation timestamp. |
| data.updated_at | date-time | Yes | Last update timestamp. |
Error responses use the shared error envelope.
/bulk-operations/:id/chunks
Inspect paginated chunk attempts and results.
Request and response schemas
Path parameters
| Field | Type | Required | Description |
|---|---|---|---|
| id | uuid | Yes | Bulk operation UUID. |
Query parameters
| Field | Type | Required | Description |
|---|---|---|---|
| limit | integer 1..100 | No | Page size; defaults to 25. |
| cursor | string | No | Opaque next_cursor returned by the previous page. |
Request body
No JSON request body.
Response 200 · BulkChunkPage
Bulk chunk page returned.
| Field | Type | Required | Description |
|---|---|---|---|
| data[].id | uuid | Yes | Chunk UUID. |
| data[].operation_id | uuid | Yes | Owning operation UUID. |
| data[].index | integer | Yes | Zero-based chunk index. |
| data[].items | object[] | Yes | Items delivered in this chunk. |
| data[].status | string | Yes | Chunk delivery state. |
| data[].attempt_count | integer | Yes | Delivery attempts. |
| data[].response_status | integer | null | No | Latest HTTP response status. |
| data[].response_body | string | null | No | Latest response body. |
| data[].error | string | null | No | Latest delivery error. |
| data[].started_at | date-time | null | No | First attempt start. |
| data[].completed_at | date-time | null | No | Terminal completion. |
| data[].inserted_at | date-time | Yes | Creation timestamp. |
| data[].updated_at | date-time | Yes | Last update timestamp. |
| meta.next_cursor | string | null | Yes | Opaque cursor for the next page. |
| meta.has_more | boolean | Yes | Whether another page is available. |
Error responses use the shared error envelope.
/bulk-operations/:id/events
List operation lifecycle events.
Request and response schemas
Path parameters
| Field | Type | Required | Description |
|---|---|---|---|
| id | uuid | Yes | Bulk operation UUID. |
Query parameters
| Field | Type | Required | Description |
|---|---|---|---|
| limit | integer 1..100 | No | Page size; defaults to 25. |
| cursor | string | No | Opaque next_cursor returned by the previous page. |
Request body
No JSON request body.
Response 200 · LifecycleEventPage
Bulk event page returned.
| Field | Type | Required | Description |
|---|---|---|---|
| data[].id | uuid | Yes | Event UUID. |
| data[].type | string | Yes | Lifecycle event type. |
| data[].actor_id | string | null | No | Actor identifier. |
| data[].data | object | Yes | Event-specific data. |
| data[].inserted_at | date-time | Yes | Persistence timestamp. |
| meta.next_cursor | string | null | Yes | Opaque cursor for the next page. |
| meta.has_more | boolean | Yes | Whether another page is available. |
Error responses use the shared error envelope.
/bulk-operations/:id/cancel
Cancel all remaining work.
Request and response schemas
Path parameters
| Field | Type | Required | Description |
|---|---|---|---|
| id | uuid | Yes | Bulk operation UUID. |
Request body · LifecycleCommandInput
| Field | Type | Required | Description |
|---|---|---|---|
| actor_id | string | No | Actor; framework proxies inject this value. |
| reason | string | No | Optional cancellation or revocation rationale. |
Response 200 · BulkOperation
Cancelled operation returned.
| Field | Type | Required | Description |
|---|---|---|---|
| data.id | uuid | Yes | Operation UUID. |
| data.project_id | uuid | Yes | Owning project UUID. |
| data.external_organization_id | string | null | Yes | Enforced organization scope. |
| data.action | string | Yes | Stable action identifier. |
| data.status | BulkStatus | Yes | Current operation state. |
| data.metadata | object | Yes | Operation metadata. |
| data.chunk_size | integer | Yes | Items per chunk. |
| data.progress | object | Yes | Item/chunk totals, outcomes, and percentage. |
| data.started_at | date-time | null | No | Processing start. |
| data.completed_at | date-time | null | No | Terminal completion. |
| data.cancelled_at | date-time | null | No | Cancellation timestamp. |
| data.inserted_at | date-time | Yes | Creation timestamp. |
| data.updated_at | date-time | Yes | Last update timestamp. |
Error responses use the shared error envelope.
/sessions
Create a short-lived end-user token from trusted claims.
Request and response schemas
Request body · SessionInput
| Field | Type | Required | Description |
|---|---|---|---|
| claims | object | Yes | Trusted end-user claims to sign into the short-lived token. |
Response 200 · Session
Signed session token returned.
| Field | Type | Required | Description |
|---|---|---|---|
| data.token | string | Yes | Signed short-lived end-user token. |
Error responses use the shared error envelope.
Framework proxy surface
The framework adapter deliberately omits POST /actions
and POST /bulk-operations
from browser routes. Action definitions synchronize server-side and Bulk creation is a privileged server operation. Every Approval Policy operation requires an explicit adapter authorization decision.
| Operation passed to authorize | Browser-allowed method and path |
|---|---|
| actions.read | GET /actions and GET /actions/:identifier |
| schedules.read | GET /schedules and GET /schedules/:id |
| schedules.create | POST /schedules |
| schedules.preview | POST /schedules/preview |
| schedules.update | PATCH /schedules/:id |
| schedules.delete | DELETE /schedules/:id |
| schedules.control | POST /schedules/:id/pause or /resume |
| schedules.history | GET /schedules/:id/runs or /events |
| runs.read | GET /runs and GET /runs/:id |
| approvals.read | GET /approvals and GET /approvals/:id |
| approvals.create | POST /approvals |
| approvals.check | POST /approvals/check |
| approvals.update | PATCH /approvals/:id |
| approvals.delete | DELETE /approvals/:id |
| approvals.decide | POST /approvals/:id/decisions, /cancel, or /revoke |
| approvals.history | GET /approvals/:id/events |
| approval_policies.read | GET /approval-policies and GET /approval-policies/:id |
| approval_policies.create | POST /approval-policies |
| approval_policies.update | PATCH /approval-policies/:id |
| approval_policies.delete | DELETE /approval-policies/:id |
| audit.read | GET /audit-events and GET /audit-events/:id |
| audit.create | POST /audit-events |
| server only | POST /audit-events/:id/tombstone |
| bulk.read | GET /bulk-operations, /:id, /:id/chunks, and /:id/events |
| bulk.cancel | POST /bulk-operations/:id/cancel |
| sessions.create | POST /sessions |
Authorize operation, resource, and application ownership
context, the exact operation above, resource, and the original Request. Bulk reads and every approval-policy operation require this callback and fail closed when it is absent. Organization-scoped callers can read project-global fallback policies but cannot mutate them.
Identity transformation
Before forwarding, the adapter recursively removes the following keys from query parameters and every nested request object: external_user_id, external_organization_id, requester_id, approver_id, actor_id, viewer_id, user_id, and organization_id.
| Request family | Trusted values injected from context |
|---|---|
| All tenant-bound operations | external_organization_id = context.organization.id |
| Schedule/Run reads | external_user_id = context.user.id |
| Schedule writes | external_user_id = user.id; external_organization_id = organization.id |
| Approval list | requester_id by default; approver_id for view=assigned; view=all still enforces organization + participant user |
| Approval create/check | requester_id |
| Decision; cancel/revoke | approver_id; actor_id |
| Audit read/write | viewer_id; actor_id |
| Bulk cancel | actor_id |
| Session create | claims merged with trusted claims, user_id, and organization_id |
Browser-supplied custom headers are ignored. The adapter supplies the project Authorization header plus protected organization/user scope headers; the platform uses those headers as authorization constraints rather than optional filters.