Skip to main content
POST
Append commands to the action ledger

Behavior

Each command carries its own idempotency_key; resending an identical batch replays the original results with status 200. actor_principal must equal X-Nexio-Acting-Principal when that header is sent. Nothing is written to the system of record. See Writes and the action ledger.

Authorizations

Authorization
string
header
required

Send the key as Authorization: Bearer <key>. Two kinds of key exist.

Organization keys are issued in the portal (Settings, then API keys), each bound to one environment, shaped nx_<environment slug>_<64 hex>. They carry no capabilities and pass every capability check, with one exception: routes under /api/v1/records, /api/v1/engines/{id}/opportunities, /api/v1/graph and /api/v1/catalog/documents accept an organization key only when its environment is live, and refuse any other with 403 scoped_key_required. Revocation takes effect within 60 seconds.

Scoped keys are issued by Nexio on request, shaped nxsk_v1_<24 hex key id>_<43 character secret>. Each is bound to one org, one environment, a set of engines and a set of capabilities. A malformed, unknown or revoked nxsk_ key fails with 401 and is never retried as an organization key. Revocation takes effect on the next request. A scoped key without a route's capability gets 403 insufficient_capability; a scoped key not bound to the engine gets 403 engine_binding_forbidden.

Key-grantable capabilities: engines:read, runs:write, runs:read, runs:defensibility:read, runs:test, catalog:read, catalog:documents:read, webhooks:manage, conversations:use, conversations:export, records:read, records:opportunities:run, actions:write, actions:read, graph:read, records:analyze.

Routes that accept organization keys only (every scoped key gets 403 insufficient_capability): environment management, engine create, update, configuration and publish, and conversation instance authoring. Each operation description names the capability a scoped key needs.

Headers

X-Nexio-Acting-Principal
string

The person the request is for, as your identity provider's stable user id. Optional on this route; when absent, the body's actor_principal is used. When both are sent they must match, or the request answers 400 invalid_request. Narrows what the key reaches.

X-Nexio-Acting-Email
string

The acting person's verified sign-in email. The seat is derived from it.

X-Nexio-Records-Assertion
string

Signed assertion v1.<unix seconds>.<hex HMAC-SHA256> over acting_principal|acting_email|reserved|timestamp (each part trimmed, the email lowercased). The third field is reserved: send an empty string. The timestamp must be within 5 minutes of the server clock, either way. Checked once Nexio enables assertion verification for your organization, when it provisions the signing secret; a missing or wrong assertion then answers 403 assertion_invalid and one outside the window 403 assertion_stale.

X-Nexio-Records-Lens
string

Do not send on this route. Any non-empty value refuses the write with 403 book_lens_read_only.

Query Parameters

connection_id
string<uuid>

The system-of-record connection to use when a command addresses a system-of-record record. Optional when the organization has exactly one qualifying connection; required when it has several (otherwise 400 book_connection_ambiguous). Ignored for a batch of Catalog notes only. A connection that does not exist in the organization answers 404 not_found.

Body

application/json
actor_principal
string
required

The person the commands are for. Must equal X-Nexio-Acting-Principal when that header is sent.

actor_type
enum<string>
required

producer for a person, agent for an AI agent acting for that person.

Available options:
producer,
agent
commands
object[]
required
Required array length: 1 - 20 elements

Response

The recorded (or replayed) commands.

duration_ms
integer
required
results
object[]
required
action_seq
integer
required

The ledger's latest sequence number.

scope
object
required

Appended to Records read envelopes, except GET /records/actions, the /records/analyses routes and GET /records/status, which carries its own scope block. States the scope the rows were served at.

serving
object

Absent when every command addresses a Catalog entity.

Last modified on September 25, 2026