Agent Actions (Internal)
This API is for first-party automation in Fieldkit (internal agents, schedulers, and worker services).
It is not part of the customer-facing public/v1 contract.
What This Gives You
- One safe way for agents to request system changes.
- Approval gates for risky actions.
- Built-in retry safety with idempotency keys.
- A machine-readable action catalog (
GET /api/v1/actions/types).
Submit Action
POST /api/v1/actions
Headers:
X-API-Key: <service-account-key>Idempotency-Key: <stable-key-for-this-request>
Body:
{
"action_type": "update_sales_order_status",
"schema_version": 1,
"target": {
"type": "sales_order",
"id": "c3a1af57-2f5a-4e85-98b1-23b3501fa9d4"
},
"scope": "FULFILLMENT",
"mode": "EXECUTE",
"preconditions": {
"expected_status": "ready"
},
"payload": {
"status": "in_production"
},
"correlation_id": "5df4f2e5-cc45-4e75-bf69-f056eae5b7c3",
"causation_id": "98de5f35-4c21-4c1a-8d13-2d1b2b4c9e9d"
}
Response:
{
"action_id": "1a5c5d78-34b1-4a0a-97a1-8f11c17a7fdb",
"event_id": "fd74f5f4-050f-40b8-8f6d-5e5392718938",
"rule_id": null,
"action_type": "update_sales_order_status",
"status": "needs_approval",
"requires_approval": true,
"scope": "FULFILLMENT",
"created_at": "2026-02-12T19:34:56Z",
"updated_at": "2026-02-12T19:34:56Z"
}
Get Action
GET /api/v1/actions/{action_id}
Returns current status plus execution ledger fields when available (attempts, started_at, completed_at, result, error).
Decide Approval
POST /api/v1/actions/{action_id}/decide
Admin-only endpoint for actions in needs_approval.
Body:
{
"decision": "APPROVE",
"reason": "Approved by on-call"
}
decision values:
APPROVEREJECT
Action Type Catalog
GET /api/v1/actions/types
Returns machine-readable metadata for every registered action:
action_typesummaryriskapproval_required_by_defaultrequired_fieldsexample_payload
This endpoint is designed for agent tooling to discover what actions exist and how to call them.
Idempotency And Retries
- Service-account write requests require
Idempotency-Key. - Same key + same request body replays the original response and sets
X-Idempotent-Replay: true. - Same key + different body returns
409withcode=IDEMPOTENCY_CONFLICT. - If a matching request is still running, the API returns
409withcode=IDEMPOTENCY_IN_PROGRESS.
Lifecycle Statuses
needs_approvalpendingrunningsucceededfailedrejected