Skip to main content

AxonFlow Agent API (11.0.0)

Download OpenAPI specification:Download

REST API for the AxonFlow Agent service - Authentication, Authorization, and Static Policy Enforcement Gateway.

The Agent serves as the entry point for all client requests, providing:

  • Proxy Mode: Full request interception and processing through the Orchestrator
  • Gateway Mode: Pre-check and audit endpoints for SDK-managed LLM calls
  • MCP (Model Context Protocol): Data connector queries and commands
  • Authentication: License and token validation
  • Static Policy Enforcement: Fast regex-based content filtering (the system policies are read-only to the application roles in v11; see the System Policies tag)

Single Entry Point

The Agent is the single entry point for all client traffic (ADR-024): clients never call the Orchestrator directly — it is an internal service and must not be exposed. Every /api/v1/* endpoint is reachable through the Agent. This spec documents the endpoints the Agent serves natively; endpoints the Agent transparently proxies to the Orchestrator (audit, decisions, overrides, plans/workflows, cost/budgets/usage, connectors, LLM-provider management, evidence, and the regulatory-compliance families — EU AI Act, SEBI, RBI, OJK/BI/UU-PDP, MAS FEAT) are documented in their canonical specs: orchestrator-api.yaml for most families, masfeat-api.yaml for MAS FEAT, and policy-api.yaml for dynamic policies. They are still called via the Agent host and port. The EU AI Act family additionally keeps pointer entries in this spec, and a few agent-native subroutes under otherwise-proxied prefixes (audit verification, connector cache refresh) are documented here as well.

Authentication

All endpoints require authentication via:

  • Authorization: Basic base64(clientId:clientSecret): OAuth2-style client credentials (recommended)
  • user_token: JWT token for user identification (in request body)

Note: clientSecret is optional for community/self-hosted deployments. clientId is recommended for request identification.

Deployment Modes

  • SaaS: Hosted by AxonFlow, multi-tenant (DEPLOYMENT_MODE=saas)
  • Enterprise: Customer-deployed (DEPLOYMENT_MODE=enterprise)
  • Community: Local development (DEPLOYMENT_MODE=community) - bypasses license validation

Health

Service health and readiness checks

Health check

Returns service health status. During startup, returns status: starting. Once fully initialized, returns status: healthy.

This endpoint responds immediately even during initialization, allowing ECS/ALB health checks to pass while the service starts up.

Responses

Response samples

Content type
application/json
Example
{
  • "status": "healthy",
  • "service": "axonflow-agent",
  • "timestamp": "2025-01-15T10:30:00Z",
  • "version": "1.0.0"
}

Proxy Mode

Full request interception and processing

Process client request

Main entry point for Proxy Mode. The Agent:

  1. Authenticates the client credential. On Enterprise it also admits the user token, which is required there: a request with no token, or one that does not verify, is refused 401. On Community and community-SaaS the credential is the principal and a user token is ignored
  2. Decides the request in ONE anchored pass: the shared static engine's evaluation is the detector input, and the ADR-065 anchored engine authors the verdict for the credential or the verified user (PRD v11 §1.1, §1.6)
  3. Forwards to the Orchestrator if allowed
  4. Returns the response with the engine that decided it

One pass since v11.0.0 (#4253). The second pass that used to follow an anchored approval - the tier engine, over static_policies' stored action column and an organization's legacy per-policy overrides - is retired. A legacy per-policy override (block or require_approval) no longer decides this route; the effective-policies read (GET /api/v1/static-policies/effective) keeps showing it under its deprecation (PRD v11 §1.11). A shipped system control whose stored action is block is still refused here, by the anchored engine, naming its policy. The agent's pass resolves no governance segments, so a segment-store outage refuses nothing at that pass (a request it forwards to the orchestrator's /api/v1/process or /api/v1/plan/execute is decided there by the anchored engine too, whose facts resolve the user's segments and refuse when that fails), and the pass never holds a request for approval: an anchored approval challenge is a refusal.

Every policy verdict names the engine that decided it (engine, always anchored), the type of principal it decided for (subject_type) and the digest of the policy bundle (policy_bundle).

The LLM response is decided too. A forwarded request's response is decided by the orchestrator response plane, on the anchored engine, and response_plane names that decision. A response it withholds answers success: false and blocked: true, and is not counted against the client's circuit breaker.

Use this endpoint when you want AxonFlow to intercept and process all LLM requests.

header Parameters
Authorization
required
string
Example: Basic bXktb3JnOkFYT04tVjIteHh4

OAuth2-style Basic authentication header. Format: Basic base64(clientId:clientSecret)

  • clientId: Your organization identifier (required)
  • clientSecret: Authentication credential (optional for community mode)

Not required when DEPLOYMENT_MODE=community.

X-Client-Secret
string
Deprecated

DEPRECATED: Use Basic authentication instead. Legacy client secret header. Prefer using Authorization: Basic header.

Request Body schema: application/json
required
query
required
string [ 1 .. 100000 ] characters

The query or prompt to process

user_token
string

JWT token for user authentication

client_id
required
string

Registered client application ID

request_type
string
Enum: "sql" "llm_chat" "rag_search" "mcp-query" "multi-agent-plan"

Type of request:

  • sql: Database query
  • llm_chat: LLM conversation
  • rag_search: RAG retrieval
  • mcp-query: MCP connector query
  • multi-agent-plan: Multi-agent planning
skip_llm
boolean
Default: false

Skip LLM calls (for testing)

object

Additional context for request processing

Array of objects

Optional multimodal payload accompanying the query (images, documents, etc.). Consumed by the platform's media-governance code path; per-item shape is MediaContent from the SDK.

Responses

Request samples

Content type
application/json
Example
{
  • "query": "Show sales data for last quarter",
  • "user_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  • "client_id": "travel-app-prod",
  • "request_type": "sql",
  • "context": {
    }
}

Response samples

Content type
application/json
{
  • "success": true,
  • "data": {
    },
  • "result": "Flight options found: UA123, AA456, DL789",
  • "plan_id": "plan_1234567890_abc123",
  • "metadata": {
    },
  • "policy_info": {
    },
  • "engine": "anchored",
  • "subject_type": "User",
  • "policy_bundle": "sha256:<the digest of the bundle that decided the request>",
  • "response_plane": {
    }
}

Preview /api/request's verdict (a dry run of its one pass)

Previews what POST /api/request would decide for the authenticated credential, through the same pass: the same detector evaluation and the same anchored enforcing seam. A policy is tested against the engine that enforces it (PRD v11 §1 item 10). It records no decision: no audit_logs row, no enforce-decision count, no circuit-breaker violation and no signed decision. The shared engine's evaluation that feeds the pass still counts in its metrics, and where the engine carries an audit queue a matched block is logged to policy_violations, as before v11.0.0.

Changed in v11.0.0 (#4253). It used to preview two legacy passes and resolve the governance segments of the body's user_email. It now decides for the credential that authenticated the call (subject_type Client): on Community as /api/request decides a request that carries no user token; on Enterprise, where /api/request requires a user token, as the credential's service identity, the way /api/v1/decide decides a token-less caller - and it is refused 401 where the organization requires a user token, as decide refuses it. user_email is accepted and ignored (a body field is not a principal), segments_resolved is no longer in the response, and the response gains engine, subject_type and policy_bundle. Where the anchored engine cannot decide, the preview answers 503, as the route does.

Request Body schema: application/json
required
query
required
string

Query to preview

user_email
string

Accepted and ignored since v11.0.0 (#4253): the preview is decided for the authenticated credential.

request_type
string

Request type

Responses

Request samples

Content type
application/json
{
  • "query": "DROP TABLE customers",
  • "request_type": "sql"
}

Response samples

Content type
application/json
{
  • "blocked": true,
  • "reason": "explicit_constraint",
  • "triggered_policies": [
    ],
  • "checks_performed": [
    ],
  • "processing_time_ms": 3,
  • "engine": "anchored",
  • "subject_type": "Client",
  • "policy_bundle": "sha256:<the digest of the bundle that decided the preview>"
}

List registered clients

Returns all registered client applications

Responses

Response samples

Content type
application/json
[
  • {
    }
]

Register a new client

Register a new client application

Request Body schema: application/json
required
id
string

Unique client identifier

name
string

Client application name

org_id
string

Organization ID for usage tracking

tenant_id
string

Tenant ID for multi-tenancy

permissions
Array of strings

Granted permissions

rate_limit
integer

Requests per minute limit

enabled
boolean

Whether client is active

license_tier
string
Enum: "Community" "starter" "professional" "enterprise"

License tier

license_expiry
string <date-time>

When license expires

Responses

Request samples

Content type
application/json
{
  • "id": "string",
  • "name": "string",
  • "org_id": "string",
  • "tenant_id": "string",
  • "permissions": [
    ],
  • "rate_limit": 0,
  • "enabled": true,
  • "license_tier": "Community",
  • "license_expiry": "2019-08-24T14:15:22Z"
}

Response samples

Content type
application/json
{
  • "id": "string",
  • "name": "string",
  • "org_id": "string",
  • "tenant_id": "string",
  • "permissions": [
    ],
  • "rate_limit": 0,
  • "enabled": true,
  • "license_tier": "Community",
  • "license_expiry": "2019-08-24T14:15:22Z"
}

Gateway Mode

Pre-check and audit for SDK-managed LLM calls

Pre-check request before LLM call

Gateway Mode Step 1: Call this endpoint before making your own LLM API call.

The Agent validates the request against policies and returns:

  • verdict - the canonical allow | deny, the same vocabulary POST /api/v1/decide uses. Read this one. Since v11 the pre-check never holds a request: a require_approval policy is a deny.
  • approved: true if the request is allowed (retained)
  • decision_id — the decision identifier. Use it for the subsequent audit call, AND for GET /api/v1/decisions/{decision_id}/explain, which is keyed on it.
  • context_id — a deprecated alias of decision_id, same value
  • Optional approved_data from MCP connectors
  • Rate limit information

approved_data is only prefetched for clean approvals (#2868): when the request is blocked, requires HITL approval, or requires redaction, connector prefetch is skipped and approved_data is never populated — governed data is not fetched for a request that may not proceed.

Context expires after 5 minutes.

Example Flow

1. SDK calls pre-check → gets context_id, approved=true
2. SDK makes direct LLM call (OpenAI, Anthropic, etc.)
3. SDK calls audit with context_id and response metadata
header Parameters
Authorization
required
string
Example: Basic bXktb3JnOkFYT04tVjIteHh4

OAuth2-style Basic authentication header. Format: Basic base64(clientId:clientSecret)

  • clientId: Your organization identifier (required)
  • clientSecret: Authentication credential (optional for community mode)

Not required when DEPLOYMENT_MODE=community.

Request Body schema: application/json
required
query
required
string non-empty

Query to validate

user_token
string

JWT token for user authentication

client_id
required
string

Client application ID

data_sources
Array of strings

MCP connectors to fetch data from

object

Additional context

Responses

Request samples

Content type
application/json
Example
{
  • "query": "What is the customer's order status?",
  • "user_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  • "client_id": "customer-portal"
}

Response samples

Content type
application/json
Example
{
  • "context_id": "ctx_abc123def456",
  • "approved": true,
  • "policies": [
    ],
  • "rate_limit": {
    },
  • "expires_at": "2025-01-15T10:35:00Z"
}

Audit LLM call after completion

Gateway Mode Step 2: Call this endpoint after your LLM API call completes.

Records:

  • Token usage for billing and quotas
  • Latency metrics
  • Provider and model information
  • Estimated cost

Requires a valid context_id from pre-check (not expired).

header Parameters
Authorization
required
string
Example: Basic bXktb3JnOkFYT04tVjIteHh4

OAuth2-style Basic authentication header. Format: Basic base64(clientId:clientSecret)

  • clientId: Your organization identifier (required)
  • clientSecret: Authentication credential (optional for community mode)

Not required when DEPLOYMENT_MODE=community.

Request Body schema: application/json
required
context_id
required
string

Context ID from pre-check

client_id
required
string

Client application ID

response_summary
string <= 500 characters

Brief summary of LLM response (for audit)

provider
required
string
Enum: "openai" "azure-openai" "anthropic" "bedrock" "ollama" "gemini"

LLM provider name

model
required
string

Model identifier

required
object (TokenUsage)
latency_ms
integer

LLM call latency in milliseconds

object

Additional metadata for audit

Responses

Request samples

Content type
application/json
{
  • "context_id": "ctx_abc123def456",
  • "client_id": "travel-app",
  • "response_summary": "Found 5 flights matching criteria",
  • "provider": "openai",
  • "model": "gpt-4",
  • "token_usage": {
    },
  • "latency_ms": 1250,
  • "metadata": {
    }
}

Response samples

Content type
application/json
{
  • "success": true,
  • "audit_id": "aud_xyz789"
}

Decision Mode

Synchronous policy decision endpoint (ADR-056). Called by an infrastructure gateway acting as a Policy Enforcement Point (PEP); AxonFlow returns a verdict (allow or deny) and the PEP enforces it. Same shared-policy engine as Gateway Mode pre-check; difference is the caller.

Policy decision for an infrastructure gateway (PEP)

Decision Mode endpoint (ADR-056 / epic #2426). The customer's infrastructure gateway (Policy Enforcement Point) calls this endpoint per request to get a verdict (allow or deny) and enforces the result. AxonFlow is consulted, never on the traffic path.

The shared-policy engine behind this endpoint is the same engine that backs Gateway Mode's POST /api/policy/pre-check. The difference is the caller: Gateway Mode is called by application code; Decision Mode is called by an infrastructure gateway.

M1 scope: static policies only (PII detection, SQL injection, dangerous patterns, RBI India PII, compliance categories) to keep the inline RPC budget in single-digit milliseconds. Dynamic/custom policy support is M2 scope per the epic.

OTel trace correlation: the response carries a W3C-compatible 32-hex trace_id. When the caller passes a traceparent header, its trace-id is reused so multi-gateway-layer decisions stitch into one end-to-end trace. Each decision also emits an OpenTelemetry span on the axonflow.agent.decision tracer.

Available at all tiers (Community through Enterprise) — the policy engine is the same one Gateway Mode uses.

header Parameters
X-Axonflow-Client
string
Example: mcp-proxy/0.3.1

Optional client-version telemetry header (<client>/<version>, e.g. mcp-proxy/0.3.1 or claude-code/1.9.1). Enterprise deployments with the client_version_telemetry capability count validated values in the axonflow_client_version_requests_total metric on the decide and MCP check-output planes. Telemetry only — never used for authentication or authorization; invalid values are ignored.

X-Axonflow-PEP-Handshake
string <= 4096 characters

The ADR-065 PEP capability handshake: base64url of a compact JSON document in which an external enforcement point declares what it is and which obligations it can discharge. See PEPHandshake for the document.

Absent is the default and changes nothing. A caller that omits the header takes byte-for-byte the path it took before this header existed.

A header that is PRESENT and cannot be read is refused, never treated as absent: degrading a malformed declaration to "legacy caller" would go on handing an enforcement point obligations it had just said it cannot discharge. The refusal is 400 and its message names this header, which matters on /api/v1/access/evaluation where the refusal is rendered through that surface's existing incomplete_evaluation code and the message is the only thing distinguishing a malformed HEADER from a malformed body ENVELOPE.

Present more than once is refused: RFC 7230 permits an intermediary to join repeated field lines with a comma, and a comma is outside the base64 alphabet, so a joined pair can only decode to malformed. That is why the document is base64 rather than raw JSON, which would join into something a lenient parser might accept.

When a decision carries a mandatory obligation the declared set does not cover, the request is answered 200 with verdict: deny and a reason beginning pep_capability_unsupported (ADR-065 invariant 8) - a decision about the request, not a transport error. Enterprise deployments only; a Community deployment records the declaration and emits the obligation as it does today.

traceparent
string
Example: 00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-01

W3C trace-context header. When present and valid, the trace-id is reused in the response so multi-layer decisions correlate into one end-to-end trace.

Request Body schema: application/json
required
stage
required
string
Enum: "llm" "tool" "agent"

Which gateway layer is calling. Maps to ADR-056's three-layer reference architecture (agent / MCP / LLM).

object (DecisionCallerIdentity)

Gateway-asserted caller identity. org_id and tenant_id are OPTIONAL in the body -- the auth-derived identity from apiAuthMiddleware is authoritative. In non-community mode, body-supplied values MUST match the authenticated identity or the request is rejected with HTTP 403.

object (DecisionTarget)

What the gateway is about to call.

query
required
string non-empty

The request body / prompt / statement being decided on.

user_token
string

Optional end-user JWT for audit identity. PEP gateways are typically services and may omit this field -- in enterprise mode the platform synthesizes a service identity for the audit row when no token is supplied. Supplying a token gets the validated-user record on the audit row instead.

object

Optional caller-supplied context (string values) that AxonFlow propagates end-to-end into the decision audit record + the OTel decision span, so a SIEM can correlate the decision with upstream logs (e.g. by session_id). Intended for infrastructure-gateway audit headers such as X-AI-Agent, X-Session-ID, X-Leader-Identity, and a tenant-scoped header family.

Only keys matching the server's allowlist (AXONFLOW_DECISION_CONTEXT_ALLOWLIST; the default covers common agent / session / leader identity headers plus a tenant-scoped header family, where a trailing * is a prefix match) are persisted; all other keys are silently dropped. Surviving keys are canonicalized to lower_snake_case (X-AI-Agentx_ai_agent) so joins are deterministic regardless of header casing. Non-string values are dropped; values are capped at 256 bytes and the map at 10 keys (surplus dropped, flagged context_truncated). The persisted map is returned (full) by GET /api/v1/decisions/{id}/explain and (truncated to 5 keys) by GET /api/v1/decisions.

fulfillment_capabilities
Array of strings
Items Enum: "request_body_redaction" "request_header_mutation"

What this PEP's seam can mechanically do to a request before forwarding it. A different axis from the capability handshake, which declares which OBLIGATIONS the enforcement point can discharge: request_header_mutation has no obligation type at all, and immutable_audit has no seam mechanic, so neither list is derivable from the other.

Three wire states, three meanings:

  • member omitted - a legacy (pre-9.11.0) caller. Obligations are emitted exactly as before.
  • [] - still a legacy caller, deliberately. These bytes have always been acceptable to the server and any non-Go client could send them, so giving them a new meaning would move an unchanged caller from "obligation emitted, the PEP fails closed" to "obligation suppressed, organization fallback posture" - default log, i.e. allowed without the redaction. Since v10.4.0 the state is representable in the Go client and distinguishable in the type; its reading is unchanged.
  • non-empty - only the obligations these capabilities can discharge are emitted; the organization's obligation-fallback posture decides what happens to any the platform suppresses.

Unknown values are ignored, never an error and never a block, so an older platform meeting a newer PEP's vocabulary degrades instead of failing.

Responses

Request samples

Content type
application/json
Example
{
  • "stage": "llm",
  • "caller_identity": {
    },
  • "target": {
    },
  • "query": "What is the customer's order status?"
}

Response samples

Content type
application/json
Example
{
  • "verdict": "allow",
  • "decision_id": "f81d4fae-7dec-11d0-a765-00a0c91e6bf6",
  • "trace_id": "0af7651916cd43dd8448eb211c80319c",
  • "stage": "llm",
  • "reasons": [ ],
  • "obligations": [ ],
  • "evaluated_policies": [ ],
  • "expires_at": "2026-05-23T10:35:00Z"
}

MCP Connectors

Model Context Protocol data connector operations

List the caller's MCP connectors

Returns the MCP connectors the authenticated tenant may reach, with their health status. Deployment-shared connectors (those registered under the wildcard tenancy *) are included for every tenant; another tenant's connectors are not (platform/agent/mcp_handler.go:612-620).

Connectors provide access to external data sources:

  • PostgreSQL
  • Cassandra
  • Salesforce
  • Snowflake
  • Amadeus (travel API)
  • Slack

Authentication. Wrapped in apiAuthMiddleware (platform/agent/mcp_handler.go:581); the tenancy comes from the credential, never from a caller-supplied header or path segment. Registered for GET only — apiAuthMiddleware forwards CORS preflights unauthenticated, so registering OPTIONS would reach the handler with no identity in context.

(Behaviour change in #3067: this route was previously registered with no auth middleware and returned every tenant's connector names, types, versions, capabilities, health and raw driver error strings to an anonymous caller.)

Authorizations:
BasicAuth(InternalServiceIDInternalServiceToken)

Responses

Response samples

Content type
application/json
{
  • "connectors": [
    ],
  • "count": 2
}

Check connector health

Returns health status for one of the authenticated tenant's connectors (or a deployment-shared one).

Naming another tenant's connector returns the same 404 as a nonexistent one — there is no existence oracle, and no live connection is opened with the other tenant's credentials (platform/agent/mcp_handler.go:665-676).

Authentication. Wrapped in apiAuthMiddleware (platform/agent/mcp_handler.go:584), GET only.

(Behaviour change in #3067: this route was previously registered with no auth middleware, so an anonymous caller could name any tenant's connector and have the agent open a live connection with that tenant's decrypted credentials.)

Authorizations:
BasicAuth(InternalServiceIDInternalServiceToken)
path Parameters
name
required
string
Example: postgres_main

Connector name. Resolved within the authenticated tenancy, with a fallback to the deployment-shared (*) tenancy.

Responses

Response samples

Content type
application/json
{
  • "healthy": true,
  • "latency_ms": 5,
  • "last_check": "2025-01-15T10:30:00Z"
}

Execute MCP query (read-only)

Execute a read-only query via an MCP connector.

This follows the MCP Resource pattern for data retrieval. For write operations, use /mcp/tools/execute.

Audit Logging

All MCP queries are automatically logged to the mcp_query_audits table with:

  • Request phase: SQLi detection results, PII blocking decisions
  • Response phase: PII redaction details, redacted field paths
  • Exfiltration checks: Row counts, volume limit violations
  • Result: Success/failure, error messages, duration

Each audit entry includes audit_id for correlation with SDK PolicyInfo. Statement content is stored as SHA256 hash for privacy.

header Parameters
Authorization
required
string
Example: Basic bXktb3JnOkFYT04tVjIteHh4

OAuth2-style Basic authentication header. Format: Basic base64(clientId:clientSecret)

  • clientId: Your organization identifier (required)
  • clientSecret: Authentication credential (optional for community mode)

Not required when DEPLOYMENT_MODE=community.

Request Body schema: application/json
required
client_id
required
string
license_key
string

Can also be provided in X-License-Key header

user_token
string
connector
required
string

Connector name

operation
string

Operation name (for API connectors like Amadeus)

statement
string

SQL/CQL statement (for database connectors)

object

Query parameters

limit
integer

Maximum rows to return

timeout
string

Timeout duration (e.g., "10s")

Responses

Request samples

Content type
application/json
Example
{
  • "client_id": "analytics-app",
  • "user_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  • "connector": "postgres_main",
  • "statement": "SELECT * FROM orders WHERE status = $1",
  • "parameters": {
    },
  • "limit": 100,
  • "timeout": "10s"
}

Response samples

Content type
application/json
{
  • "success": true,
  • "connector": "amadeus",
  • "data": [
    ],
  • "row_count": 5,
  • "duration_ms": 450,
  • "engine": "anchored",
  • "subject_type": "User",
  • "policy_bundle": "sha256:4b8f2a7c9e1d3f5a6b8c0d2e4f6a8b0c2d4e6f8a0b2c4d6e8f0a2b4c6d8e0f2a",
  • "policy_packs": [
    ]
}

Execute MCP command (write)

Execute a write command via an MCP connector.

This follows the MCP Tool pattern for data modification. For read operations, use /mcp/resources/query.

Audit Logging

All MCP execute operations are automatically logged to the mcp_query_audits table with:

  • Request phase: SQLi detection results, dangerous operation blocking
  • Result: Rows affected, success/failure, error messages, duration

Each audit entry includes audit_id for correlation. Operation type (INSERT, UPDATE, DELETE) is stored in the operation field.

header Parameters
Authorization
required
string
Example: Basic bXktb3JnOkFYT04tVjIteHh4

OAuth2-style Basic authentication header. Format: Basic base64(clientId:clientSecret)

  • clientId: Your organization identifier (required)
  • clientSecret: Authentication credential (optional for community mode)

Not required when DEPLOYMENT_MODE=community.

Request Body schema: application/json
required
client_id
required
string
license_key
string
user_token
string
connector
required
string
operation
string
action
required
string
Enum: "INSERT" "UPDATE" "DELETE"
statement
string
object
timeout
string

Responses

Request samples

Content type
application/json
{
  • "client_id": "order-service",
  • "user_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  • "connector": "postgres_main",
  • "action": "UPDATE",
  • "statement": "UPDATE orders SET status = $1 WHERE id = $2",
  • "parameters": {
    },
  • "timeout": "5s"
}

Response samples

Content type
application/json
{
  • "success": true,
  • "connector": "postgres_main",
  • "rows_affected": 1,
  • "duration_ms": 15,
  • "message": "Update successful",
  • "engine": "anchored",
  • "subject_type": "User",
  • "policy_bundle": "sha256:4b8f2a7c9e1d3f5a6b8c0d2e4f6a8b0c2d4e6f8a0b2c4d6e8f0a2b4c6d8e0f2a",
  • "policy_packs": [
    ]
}

Validate MCP input against policies

Validate an MCP request (query or command) against configured policies without executing it.

This endpoint enables external orchestrators (LangGraph, CrewAI, custom pipelines) to use AxonFlow as a policy gate while managing MCP connector execution themselves.

Policy Evaluation

The anchored decision engine (ADR-065) decides the request from the organization's active typed policy document: the system detectors (SQL injection, dangerous queries, PII) run over the statement and its parameters, and the engine's verdict is the response. Tenant dynamic policies no longer decide MCP requests (PRD v11 §1.2).

If the engine denies the request, the response returns allowed: false with a block_reason. A request the engine cannot decide is refused with 503; it is never let through (PRD v11 §1.7).

When to Use

Use check-input + check-output when your orchestrator manages MCP execution natively. Use /mcp/resources/query or /mcp/tools/execute when you want AxonFlow to handle both policy enforcement and connector execution.

Audit Logging

All check-input evaluations are logged to the mcp_query_audits table with operation: "check-input" for compliance tracking. Audit entries include parameters_hash (SHA-256) and parameter_count for forensic analysis.

header Parameters
Idempotency-Key
string [ 1 .. 256 ] characters ^[A-Za-z0-9_.:\-/]+$
Example: n8n-exec-abc123-node-Approve

Optional per-request dedup token. When supplied on POST /api/v1/mcp/check-input, POST /api/v1/audit/tool-call, or POST /api/v1/hitl/queue, the platform caches the original response for 24h and returns it byte-for-byte on subsequent requests carrying the same key + same authenticated tenant + same endpoint.

Format: 1-256 chars, ^[A-Za-z0-9_.:\-/]+$. Workflow IDs from n8n, ADK, or generic SDKs all fall inside this set. A malformed key returns 400 before the handler runs.

Cache rules: 2xx + 4xx responses are cached; 5xx is NOT cached so the caller's retry can hit a fresh attempt. A cache hit returns the original response plus an Idempotent-Replayed: true response header.

Cross-tenant collisions are impossible: tenant_id participates in the primary key + an RLS policy on the storage table. Two tenants using the same key value get distinct rows.

Request Body schema: application/json
required
client_id
string

Client identifier (required in Enterprise mode)

user_token
string

JWT user token (required in Enterprise mode)

tenant_id
string

Tenant identifier (required in Enterprise mode, defaults to "default" in Community)

user_id
string

Optional end-user identifier. Honored only for internal-service callers, which may assert the end user; it attributes the decision's audit row

user_role
string

Optional end-user role (e.g., "admin", "analyst"). Honored only for internal-service callers; recorded on the decision's audit row

connector_type
required
string

MCP connector/server type (e.g., "postgres", "snowflake", "salesforce")

tool
string

Optional tool identifier being invoked, distinct from connector_type/server (#2904). Feeds capability-scoped policy evaluation when set.

statement
required
string

The SQL query or command to validate against policies

object

Optional query parameters. Values are individually scanned for SQLi, PII, and compliance violations by the static policy engine. String values are scanned directly; nested objects/arrays are JSON-serialized before scanning; numeric values are converted to strings for PII/compliance detection. Boolean values are skipped.

operation
string
Default: "execute"
Enum: "query" "execute"

Operation type. Under the read-only posture it classifies the call as a read or a write (classifyMCPCall in platform/agent/mcp_handler.go)

content_type
string

Declared content type of statement (ADR-056). Defaults to text/plain when omitted. When set to a value no registered detector handles, the request is rejected with 415 and a canonical blocked audit row tagged content_type_unsupported is written (fail-closed; see the 415 response). Source of truth: platform/agent/mcp_handler.go (MCPCheckInputRequest).

Responses

Request samples

Content type
application/json
Example
{
  • "client_id": "analytics-app",
  • "user_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  • "tenant_id": "tenant-123",
  • "connector_type": "postgres",
  • "statement": "SELECT name, email FROM users WHERE id = $1",
  • "parameters": {
    },
  • "operation": "query"
}

Response samples

Content type
application/json
{
  • "allowed": true,
  • "policies_evaluated": 12
}

Validate MCP output against policies

Validate MCP response data against configured policies without having executed the query through AxonFlow.

This endpoint enables external orchestrators to apply AxonFlow's output-side policy enforcement (PII redaction, exfiltration limits, SQLi response scanning) to data they fetched from MCP connectors independently.

Policy Evaluation

The following checks are applied in order:

  1. SQLi response scanning: Detects SQL injection artifacts in response data
  2. Static response policies: PII detection and redaction (SSN, credit card, Aadhaar, etc.)
  3. Exfiltration limits (query-style only): Row count and byte size limits

If PII is detected, the response includes redacted_data with masked values. If exfiltration limits are exceeded, the response returns allowed: false.

Query vs Execute Responses

  • Query responses (response_data): Full policy evaluation including exfiltration checks
  • Execute responses (message): SQLi scanning and PII checks only (no exfiltration limits)

Audit Logging

All check-output evaluations are logged to the mcp_query_audits table with operation: "check-output" for compliance tracking.

header Parameters
X-Axonflow-Client
string
Example: mcp-proxy/0.3.1

Optional client-version telemetry header (<client>/<version>, e.g. mcp-proxy/0.3.1 or claude-code/1.9.1). Enterprise deployments with the client_version_telemetry capability count validated values in the axonflow_client_version_requests_total metric on the decide and MCP check-output planes. Telemetry only — never used for authentication or authorization; invalid values are ignored.

Request Body schema: application/json
required
Any of
client_id
string

Client identifier (required in Enterprise mode)

user_token
string

JWT user token (required in Enterprise mode)

tenant_id
string

Tenant identifier (required in Enterprise mode, defaults to "default" in Community)

user_id
string

Optional user identifier

connector_type
required
string

MCP connector/server type (e.g., "postgres", "snowflake", "salesforce")

tool
string

Optional tool identifier whose output is being validated, distinct from connector_type/server (#2904/#2955). Feeds capability-scoped response evaluation when set (a text-document tool's output skips execution-class detectors); omitted → full (fail-closed) evaluation, no fallback from connector_type.

required
Array of objects

Query-style response rows to validate

message
string

Execute-style response message (e.g., "5 rows affected")

object

Connector metadata for SQLi response scanning (e.g., query echo, database name)

row_count
integer

Total number of rows returned (used for exfiltration limit checks)

Responses

Request samples

Content type
application/json
Example
{
  • "client_id": "analytics-app",
  • "user_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  • "tenant_id": "tenant-123",
  • "connector_type": "postgres",
  • "tool": "query",
  • "response_data": [
    ],
  • "row_count": 1
}

Response samples

Content type
application/json
Example
{
  • "allowed": true,
  • "policies_evaluated": 8,
  • "engine": "anchored",
  • "subject_type": "User",
  • "policy_bundle": "sha256:4b8f2a7c9e1d3f5a6b8c0d2e4f6a8b0c2d4e6f8a0b2c4d6e8f0a2b4c6d8e0f2a",
  • "policy_packs": [
    ]
}

Overall MCP health

Unauthenticated liveness probe.

⚠️ healthy_count + unhealthy_count do not sum to total_connectors, by design (platform/agent/mcp_handler.go:3377-3405). Because this route is anonymous, the live health checks it performs are limited to the deployment-shared (operator-configured, wildcard-tenancy *) connectors, while total_connectors keeps its pre-existing deployment-wide meaning so operator dashboards do not silently change scale. A deployment consisting only of tenant-owned connectors therefore reports healthy: true with zero counts even if every backend is down.

Use the authenticated GET /mcp/connectors for per-tenant connector health.

(Behaviour change in #3067: this route previously opened a live connection to every tenant's backend on every anonymous GET — cross-tenant credential use plus a free amplification lever.)

Responses

Response samples

Content type
application/json
{
  • "healthy": true,
  • "total_connectors": 3,
  • "healthy_count": 1,
  • "unhealthy_count": 0,
  • "timestamp": "2026-07-28T10:30:00Z"
}

Refresh the caller's connector caches

Invalidates and refreshes cached connector instances. Use this after configuration changes or deployments.

The scope depends on which credential you present (platform/agent/connector_refresh_api.go:184-216):

Credential Scope message tenant_id
Basic auth (tenant) the authenticated tenant's connectors only Tenant connector caches refreshed present
Internal-service every tenant's connectors All connector caches refreshed absent

Performance impact: the next request for each evicted connector incurs factory-creation overhead.

Authentication. This route is wrapped in apiAuthMiddleware (platform/agent/connector_refresh_api.go:123) and the tenancy comes from the authenticated identity — a caller can no longer evict another tenant's pool. Supply either:

  • Authorization: Basic base64(clientId:clientSecret) — the tenant lane (no credentials are required when DEPLOYMENT_MODE=community); or
  • X-Internal-Service-ID + X-Internal-Service-Token — the operator lane, which is the only way to trigger a deployment-wide eviction.

(Historical note: these four routes were registered with no auth middleware at all — #2883. They are authenticated as of #3067; the pre-#3067 "deploy behind network-level controls" advisory no longer applies.)

stats.cached_connectors is structurally 0 on this route: the refresh empties the scope immediately before the count is taken. That is the success signal, not a failure.

Authorizations:
BasicAuth(InternalServiceIDInternalServiceToken)

Responses

Response samples

Content type
application/json
Example
{
  • "success": true,
  • "message": "Tenant connector caches refreshed",
  • "scope": "all",
  • "tenant_id": "acme-corp",
  • "duration": "12.345ms",
  • "stats": {
    }
}

Refresh tenant connector caches

Invalidates and refreshes all cached connector instances for a tenant. Use this after updating a tenant's connector configuration.

{tenant_id} is not a selector. It is validated against the identity apiAuthMiddleware resolved and a mismatch is 403 (platform/agent/connector_refresh_api.go:152-156); the tenancy that is actually refreshed always comes from the credential.

  • Basic auth: the resolved identity is your licensed org, so this route can only ever refresh your own pool.
  • Internal-service credential: the resolved identity is whatever X-Tenant-ID you send (platform/agent/authenticator.go:127-130), so an operator targets a named tenant by sending that header and the matching path segment. Naming a tenant in the path with no X-Tenant-ID is 403, because the identity then falls back to the synthetic orchestrator-internal client id.

stats.cached_connectors is structurally 0 on this route — the refresh empties the tenant's scope immediately before the count is taken.

Authorizations:
BasicAuth(InternalServiceIDInternalServiceToken)
path Parameters
tenant_id
required
string
Example: acme-corp

The tenant whose connectors should be refreshed. Must equal the authenticated tenant — see the description.

Responses

Response samples

Content type
application/json
{
  • "success": true,
  • "message": "Tenant connector caches refreshed",
  • "scope": "tenant",
  • "tenant_id": "acme-corp",
  • "duration": "2.456ms",
  • "stats": {
    }
}

Refresh specific connector cache

Invalidates and refreshes a specific connector instance for a tenant. Use this after updating a single connector's credentials or configuration.

{tenant_id} is not a selector — same contract as POST /api/v1/connectors/refresh/{tenant_id}: the segment is validated against the authenticated identity and a mismatch is 403 (platform/agent/connector_refresh_api.go:152-156).

Unlike the two broader refresh routes, stats.cached_connectors here is informative: it is the caller's remaining cached-connector count after this one connector was evicted (platform/agent/connector_refresh_api.go:314,404-408).

Authorizations:
BasicAuth(InternalServiceIDInternalServiceToken)
path Parameters
tenant_id
required
string
Example: acme-corp

The tenant that owns the connector. Must equal the authenticated tenant — see the description.

connector_name
required
string
Example: customer-db

The connector name to refresh

Responses

Response samples

Content type
application/json
{
  • "success": true,
  • "message": "Connector cache refreshed",
  • "scope": "connector",
  • "tenant_id": "acme-corp",
  • "connector": "customer-db",
  • "duration": "0.789ms",
  • "stats": {
    }
}

Get connector cache statistics

Returns the caller's cached-connector count. The response is tenant-scoped (platform/agent/connector_refresh_api.go:350-355): cached_connectors is the authenticated tenant's own count, not the deployment's.

The cache-health counters are operator telemetry. hits, misses, evictions, factory_creations, factory_failures, connection_errors, hit_rate_percent, last_eviction and last_factory_create are deployment-wide figures. They appear here only inside a deployment object, and only for the internal-service credential (platform/agent/connector_refresh_api.go:356-369). A tenant caller must not read their absence as zero — it has no cache-health data on this surface.

Un-scoped equivalents for five of them are always available to operators on /prometheus as axonflow_connector_cache_stats{stat="cached_connectors"|"hits"|"misses"|"evictions"|"hit_rate"}, refreshed on every call to this endpoint (platform/agent/connector_refresh_api.go:338-342). factory_creations, factory_failures, connection_errors, last_eviction and last_factory_create have no Prometheus series — the deployment block is their only surface.

Authentication. Wrapped in apiAuthMiddleware (platform/agent/connector_refresh_api.go:132). This route takes no {tenant_id} path segment, so it never returns 403.

(Historical note: this route was registered with no auth middleware at all and served the deployment-wide counters to anonymous callers — #2883, where the evictions delta was an existence oracle for (tenant, connector) pairs. Authenticated and scoped as of #3067.)

Authorizations:
BasicAuth(InternalServiceIDInternalServiceToken)

Responses

Response samples

Content type
application/json
Example
{
  • "cached_connectors": 15,
  • "registry_enabled": true,
  • "tenant_id": "acme-corp",
  • "timestamp": "2026-07-28T14:25:00.123456Z"
}

Metrics

Performance monitoring and observability

Get performance metrics

Returns real-time performance metrics including:

  • Request counts (total, success, failed, blocked)
  • Latency percentiles (P50, P95, P99)
  • Per-stage timing (auth, policy, network)
  • Request type breakdown
  • Connector metrics

Responses

Response samples

Content type
application/json
{
  • "agent_metrics": {
    },
  • "health": {
    },
  • "request_types": {
    },
  • "connectors": {
    },
  • "timestamp": "2019-08-24T14:15:22Z"
}

Prometheus metrics endpoint

Returns metrics in Prometheus exposition format for scraping

Responses

HITL

Human-in-the-Loop decision queue (EU AI Act Article 14). Route high-risk AI decisions for human review before execution.

Create HITL approval request

Route a high-risk AI decision for human review. EU AI Act Article 14 requires human oversight for high-risk AI systems.

Requires both X-Org-ID and X-Tenant-ID headers (stamped by the auth middleware) — 400 when either is missing.

Enterprise only — community builds expose only GET /api/v1/hitl/status.

header Parameters
Authorization
required
string
Example: Basic bXktb3JnOkFYT04tVjIteHh4

OAuth2-style Basic authentication header. Format: Basic base64(clientId:clientSecret)

  • clientId: Your organization identifier (required)
  • clientSecret: Authentication credential (optional for community mode)

Not required when DEPLOYMENT_MODE=community.

Idempotency-Key
string [ 1 .. 256 ] characters ^[A-Za-z0-9_.:\-/]+$
Example: n8n-exec-abc123-node-Approve

Optional per-request dedup token. When supplied on POST /api/v1/mcp/check-input, POST /api/v1/audit/tool-call, or POST /api/v1/hitl/queue, the platform caches the original response for 24h and returns it byte-for-byte on subsequent requests carrying the same key + same authenticated tenant + same endpoint.

Format: 1-256 chars, ^[A-Za-z0-9_.:\-/]+$. Workflow IDs from n8n, ADK, or generic SDKs all fall inside this set. A malformed key returns 400 before the handler runs.

Cache rules: 2xx + 4xx responses are cached; 5xx is NOT cached so the caller's retry can hit a fresh attempt. A cache hit returns the original response plus an Idempotent-Replayed: true response header.

Cross-tenant collisions are impossible: tenant_id participates in the primary key + an RLS policy on the storage table. Two tenants using the same key value get distinct rows.

Request Body schema: application/json
required
client_id
required
string
user_id
string
original_query
required
string

The query/action awaiting human review

request_type
required
string

Request classification (e.g. mcp_query, llm_chat)

object
triggered_policy_id
required
string
triggered_policy_name
required
string
trigger_reason
required
string
severity
string
Enum: "low" "medium" "high" "critical"
eu_ai_act_article
string
compliance_framework
string
risk_classification
string
expires_in_seconds
integer

TTL before the request auto-expires

notify_url
string <uri>

Optional outbound webhook URL fired asynchronously after the request transitions to a terminal state (approved / rejected / overridden / expired). Must use https:// or http://. The platform signs the envelope with HMAC-SHA256 over the body keyed by the deployment's AXONFLOW_HITL_WEBHOOK_SIGNING_KEY, sent as X-AxonFlow-Signature: sha256=<hex>. See the HITLWebhookEnvelope schema and docs.getaxonflow.com/docs/governance/hitl for the full shape + verification recipe.

Responses

Request samples

Content type
application/json
{
  • "client_id": "string",
  • "user_id": "string",
  • "original_query": "string",
  • "request_type": "string",
  • "request_context": { },
  • "triggered_policy_id": "string",
  • "triggered_policy_name": "string",
  • "trigger_reason": "string",
  • "severity": "low",
  • "eu_ai_act_article": "string",
  • "compliance_framework": "string",
  • "risk_classification": "string",
  • "expires_in_seconds": 0,
  • "notify_url": "http://example.com"
}

Response samples

Content type
application/json
{
  • "success": true,
  • "data": {
    }
}

List HITL approval requests

Retrieve approval requests, filtered and paginated. Tenant scoping comes from the authenticated request context (RLS), not a query parameter.

query Parameters
status
string
Example: status=pending

Comma-separated status filter (e.g. pending or pending,approved)

severity
string
Example: severity=high,critical

Comma-separated severity filter

policy_id
string
client_id
string
user_id
string
request_type
string
Example: request_type=wcp_step_gate

Narrow the listing to one request_type.

Default behaviour without it (#3408): the listing is the ACTIONABLE queue and EXCLUDES wcp_step_gate entries. Those mirror a Workflow Control Plane step gate whose approval is resolved on the workflow plane (POST /api/v1/workflows/{workflow_id}/steps/{step_id}/approve); approving one here changes a status and releases nothing, so leaving them in rendered one workflow gate as two rows in the portal's merged Approvals queue and double-counted it in the sidebar badge. They are retained as the EU AI Act Article 14 oversight record and are returned by asking for them explicitly: ?request_type=wcp_step_gate.

meta.total follows the same predicate as the returned rows, so a client that renders a badge from it and a page from data cannot disagree.

limit
integer
Default: 50
offset
integer
Default: 0
order_by
string
order_dir
string
Enum: "asc" "desc"
header Parameters
Authorization
required
string
Example: Basic bXktb3JnOkFYT04tVjIteHh4

OAuth2-style Basic authentication header. Format: Basic base64(clientId:clientSecret)

  • clientId: Your organization identifier (required)
  • clientSecret: Authentication credential (optional for community mode)

Not required when DEPLOYMENT_MODE=community.

Responses

Response samples

Content type
application/json
{
  • "success": true,
  • "data": [
    ],
  • "meta": {
    }
}

Get HITL approval request

path Parameters
id
required
string <uuid>

The request UUID (request_id)

header Parameters
Authorization
required
string
Example: Basic bXktb3JnOkFYT04tVjIteHh4

OAuth2-style Basic authentication header. Format: Basic base64(clientId:clientSecret)

  • clientId: Your organization identifier (required)
  • clientSecret: Authentication credential (optional for community mode)

Not required when DEPLOYMENT_MODE=community.

Responses

Response samples

Content type
application/json
{
  • "success": true,
  • "data": {
    }
}

Approve HITL request

Approve a pending request to allow AI execution

path Parameters
id
required
string <uuid>
header Parameters
Authorization
required
string
Example: Basic bXktb3JnOkFYT04tVjIteHh4

OAuth2-style Basic authentication header. Format: Basic base64(clientId:clientSecret)

  • clientId: Your organization identifier (required)
  • clientSecret: Authentication credential (optional for community mode)

Not required when DEPLOYMENT_MODE=community.

Request Body schema: application/json
required
reviewer_id
string
reviewer_email
string
reviewer_role
string
comment
string

Responses

Request samples

Content type
application/json
{
  • "reviewer_id": "string",
  • "reviewer_email": "string",
  • "reviewer_role": "string",
  • "comment": "string"
}

Response samples

Content type
application/json
{
  • "success": true,
  • "data": {
    }
}

Reject HITL request

Reject a pending request to block AI execution

path Parameters
id
required
string <uuid>
header Parameters
Authorization
required
string
Example: Basic bXktb3JnOkFYT04tVjIteHh4

OAuth2-style Basic authentication header. Format: Basic base64(clientId:clientSecret)

  • clientId: Your organization identifier (required)
  • clientSecret: Authentication credential (optional for community mode)

Not required when DEPLOYMENT_MODE=community.

Request Body schema: application/json
required
reviewer_id
string
reviewer_email
string
reviewer_role
string
comment
string

Responses

Request samples

Content type
application/json
{
  • "reviewer_id": "string",
  • "reviewer_email": "string",
  • "reviewer_role": "string",
  • "comment": "string"
}

Response samples

Content type
application/json
{
  • "success": true,
  • "data": {
    }
}

Override HITL request

Record an authorized override of a pending request — the caller takes responsibility for letting the action proceed outside the normal approve/reject flow. Requires a justification for the audit trail.

path Parameters
id
required
string <uuid>
header Parameters
Authorization
required
string
Example: Basic bXktb3JnOkFYT04tVjIteHh4

OAuth2-style Basic authentication header. Format: Basic base64(clientId:clientSecret)

  • clientId: Your organization identifier (required)
  • clientSecret: Authentication credential (optional for community mode)

Not required when DEPLOYMENT_MODE=community.

Request Body schema: application/json
required
justification
string

Required by the service — missing justification returns 400

authorized_by_id
string
authorized_by_email
string
authorized_by_role
string

Responses

Request samples

Content type
application/json
{
  • "justification": "string",
  • "authorized_by_id": "string",
  • "authorized_by_email": "string",
  • "authorized_by_role": "string"
}

Response samples

Content type
application/json
{
  • "success": true,
  • "data": {
    }
}

Get HITL request audit history

Immutable audit-trail entries for a request (create/approve/reject/override/expire actions).

path Parameters
id
required
string <uuid>
header Parameters
Authorization
required
string
Example: Basic bXktb3JnOkFYT04tVjIteHh4

OAuth2-style Basic authentication header. Format: Basic base64(clientId:clientSecret)

  • clientId: Your organization identifier (required)
  • clientSecret: Authentication credential (optional for community mode)

Not required when DEPLOYMENT_MODE=community.

Responses

Response samples

Content type
application/json
{
  • "success": true,
  • "data": [
    ]
}

Pending-queue statistics

Dashboard summary of the pending queue for the caller's org. Requires the X-Org-ID header (400 when missing).

header Parameters
Authorization
required
string
Example: Basic bXktb3JnOkFYT04tVjIteHh4

OAuth2-style Basic authentication header. Format: Basic base64(clientId:clientSecret)

  • clientId: Your organization identifier (required)
  • clientSecret: Authentication credential (optional for community mode)

Not required when DEPLOYMENT_MODE=community.

Responses

Response samples

Content type
application/json
{
  • "success": true,
  • "data": {
    }
}

HITL feature status

Reports whether HITL is enabled and which features are available. This is the only HITL endpoint present in community builds (returns enabled: false, mode: "community"); Enterprise builds return enabled: true, mode: "enterprise" plus a feature map (queue, approve_reject, override, expiration, audit_history, pending_summary, notify_url, idempotency_key).

header Parameters
Authorization
required
string
Example: Basic bXktb3JnOkFYT04tVjIteHh4

OAuth2-style Basic authentication header. Format: Basic base64(clientId:clientSecret)

  • clientId: Your organization identifier (required)
  • clientSecret: Authentication credential (optional for community mode)

Not required when DEPLOYMENT_MODE=community.

Responses

Response samples

Content type
application/json
{
  • "enabled": true,
  • "mode": "community",
  • "features": {
    }
}

Expire stale pending requests

Sweeps pending requests past their expires_at into the expired state and returns the count. Intended for schedulers/ops automation; the platform also expires lazily.

header Parameters
Authorization
required
string
Example: Basic bXktb3JnOkFYT04tVjIteHh4

OAuth2-style Basic authentication header. Format: Basic base64(clientId:clientSecret)

  • clientId: Your organization identifier (required)
  • clientSecret: Authentication credential (optional for community mode)

Not required when DEPLOYMENT_MODE=community.

Responses

Response samples

Content type
application/json
{
  • "success": true,
  • "data": {
    }
}

EU AI Act (Proxied)

EU AI Act compliance module (conformity assessments, accuracy monitoring, evidence exports). Served by the orchestrator and PROXIED through the agent (/api/v1/euaiact/*) per the single-entry-point architecture — clients call the agent, never the orchestrator. Canonical operation schemas live in orchestrator-api.yaml. Enterprise only.

List compliance evidence exports (proxied to orchestrator)

Agent-proxied. Canonical contract in orchestrator-api.yaml GET /api/v1/euaiact/export.

header Parameters
Authorization
required
string
Example: Basic bXktb3JnOkFYT04tVjIteHh4

OAuth2-style Basic authentication header. Format: Basic base64(clientId:clientSecret)

  • clientId: Your organization identifier (required)
  • clientSecret: Authentication credential (optional for community mode)

Not required when DEPLOYMENT_MODE=community.

Responses

Create a compliance evidence export (proxied to orchestrator)

Agent-proxied. Canonical contract in orchestrator-api.yaml POST /api/v1/euaiact/export.

header Parameters
Authorization
required
string
Example: Basic bXktb3JnOkFYT04tVjIteHh4

OAuth2-style Basic authentication header. Format: Basic base64(clientId:clientSecret)

  • clientId: Your organization identifier (required)
  • clientSecret: Authentication credential (optional for community mode)

Not required when DEPLOYMENT_MODE=community.

Responses

Get an export request (proxied to orchestrator)

Agent-proxied. Canonical contract in orchestrator-api.yaml.

path Parameters
export_id
required
string

Export request identifier

header Parameters
Authorization
required
string
Example: Basic bXktb3JnOkFYT04tVjIteHh4

OAuth2-style Basic authentication header. Format: Basic base64(clientId:clientSecret)

  • clientId: Your organization identifier (required)
  • clientSecret: Authentication credential (optional for community mode)

Not required when DEPLOYMENT_MODE=community.

Responses

Download a completed export (proxied to orchestrator)

Agent-proxied. Canonical contract in orchestrator-api.yaml.

path Parameters
export_id
required
string

Export request identifier

header Parameters
Authorization
required
string
Example: Basic bXktb3JnOkFYT04tVjIteHh4

OAuth2-style Basic authentication header. Format: Basic base64(clientId:clientSecret)

  • clientId: Your organization identifier (required)
  • clientSecret: Authentication credential (optional for community mode)

Not required when DEPLOYMENT_MODE=community.

Responses

List conformity assessments (proxied to orchestrator)

Agent-proxied. Canonical contract in orchestrator-api.yaml GET /api/v1/euaiact/conformity.

header Parameters
Authorization
required
string
Example: Basic bXktb3JnOkFYT04tVjIteHh4

OAuth2-style Basic authentication header. Format: Basic base64(clientId:clientSecret)

  • clientId: Your organization identifier (required)
  • clientSecret: Authentication credential (optional for community mode)

Not required when DEPLOYMENT_MODE=community.

Responses

Create a conformity assessment (proxied to orchestrator)

Agent-proxied. Canonical contract in orchestrator-api.yaml POST /api/v1/euaiact/conformity.

header Parameters
Authorization
required
string
Example: Basic bXktb3JnOkFYT04tVjIteHh4

OAuth2-style Basic authentication header. Format: Basic base64(clientId:clientSecret)

  • clientId: Your organization identifier (required)
  • clientSecret: Authentication credential (optional for community mode)

Not required when DEPLOYMENT_MODE=community.

Responses

Get a conformity assessment (proxied to orchestrator)

Agent-proxied. Canonical contract in orchestrator-api.yaml.

path Parameters
assessment_id
required
string

Conformity assessment identifier

header Parameters
Authorization
required
string
Example: Basic bXktb3JnOkFYT04tVjIteHh4

OAuth2-style Basic authentication header. Format: Basic base64(clientId:clientSecret)

  • clientId: Your organization identifier (required)
  • clientSecret: Authentication credential (optional for community mode)

Not required when DEPLOYMENT_MODE=community.

Responses

Update a conformity assessment (proxied to orchestrator)

Agent-proxied. Canonical contract in orchestrator-api.yaml.

path Parameters
assessment_id
required
string

Conformity assessment identifier

header Parameters
Authorization
required
string
Example: Basic bXktb3JnOkFYT04tVjIteHh4

OAuth2-style Basic authentication header. Format: Basic base64(clientId:clientSecret)

  • clientId: Your organization identifier (required)
  • clientSecret: Authentication credential (optional for community mode)

Not required when DEPLOYMENT_MODE=community.

Responses

Submit an assessment for review (proxied to orchestrator)

Agent-proxied. Canonical contract in orchestrator-api.yaml.

path Parameters
assessment_id
required
string

Conformity assessment identifier

header Parameters
Authorization
required
string
Example: Basic bXktb3JnOkFYT04tVjIteHh4

OAuth2-style Basic authentication header. Format: Basic base64(clientId:clientSecret)

  • clientId: Your organization identifier (required)
  • clientSecret: Authentication credential (optional for community mode)

Not required when DEPLOYMENT_MODE=community.

Responses

Approve an assessment (proxied to orchestrator)

Agent-proxied. Canonical contract in orchestrator-api.yaml.

path Parameters
assessment_id
required
string

Conformity assessment identifier

header Parameters
Authorization
required
string
Example: Basic bXktb3JnOkFYT04tVjIteHh4

OAuth2-style Basic authentication header. Format: Basic base64(clientId:clientSecret)

  • clientId: Your organization identifier (required)
  • clientSecret: Authentication credential (optional for community mode)

Not required when DEPLOYMENT_MODE=community.

Responses

Reject an assessment (proxied to orchestrator)

Agent-proxied. Canonical contract in orchestrator-api.yaml.

path Parameters
assessment_id
required
string

Conformity assessment identifier

header Parameters
Authorization
required
string
Example: Basic bXktb3JnOkFYT04tVjIteHh4

OAuth2-style Basic authentication header. Format: Basic base64(clientId:clientSecret)

  • clientId: Your organization identifier (required)
  • clientSecret: Authentication credential (optional for community mode)

Not required when DEPLOYMENT_MODE=community.

Responses

Accuracy summary (proxied to orchestrator)

Agent-proxied. Canonical contract in orchestrator-api.yaml GET /api/v1/euaiact/accuracy.

header Parameters
Authorization
required
string
Example: Basic bXktb3JnOkFYT04tVjIteHh4

OAuth2-style Basic authentication header. Format: Basic base64(clientId:clientSecret)

  • clientId: Your organization identifier (required)
  • clientSecret: Authentication credential (optional for community mode)

Not required when DEPLOYMENT_MODE=community.

Responses

Record an accuracy metric (proxied to orchestrator)

Agent-proxied. Canonical contract in orchestrator-api.yaml.

header Parameters
Authorization
required
string
Example: Basic bXktb3JnOkFYT04tVjIteHh4

OAuth2-style Basic authentication header. Format: Basic base64(clientId:clientSecret)

  • clientId: Your organization identifier (required)
  • clientSecret: Authentication credential (optional for community mode)

Not required when DEPLOYMENT_MODE=community.

Responses

Record a bias measurement (proxied to orchestrator)

Agent-proxied. Canonical contract in orchestrator-api.yaml.

header Parameters
Authorization
required
string
Example: Basic bXktb3JnOkFYT04tVjIteHh4

OAuth2-style Basic authentication header. Format: Basic base64(clientId:clientSecret)

  • clientId: Your organization identifier (required)
  • clientSecret: Authentication credential (optional for community mode)

Not required when DEPLOYMENT_MODE=community.

Responses

Accuracy metric history (proxied to orchestrator)

Agent-proxied. Canonical contract in orchestrator-api.yaml.

header Parameters
Authorization
required
string
Example: Basic bXktb3JnOkFYT04tVjIteHh4

OAuth2-style Basic authentication header. Format: Basic base64(clientId:clientSecret)

  • clientId: Your organization identifier (required)
  • clientSecret: Authentication credential (optional for community mode)

Not required when DEPLOYMENT_MODE=community.

Responses

List accuracy alerts (proxied to orchestrator)

Agent-proxied. Canonical contract in orchestrator-api.yaml.

header Parameters
Authorization
required
string
Example: Basic bXktb3JnOkFYT04tVjIteHh4

OAuth2-style Basic authentication header. Format: Basic base64(clientId:clientSecret)

  • clientId: Your organization identifier (required)
  • clientSecret: Authentication credential (optional for community mode)

Not required when DEPLOYMENT_MODE=community.

Responses

Circuit Breaker

Emergency circuit breaker for AI operations (EU AI Act Article 14). Instantly halt AI operations with two-person deactivation requirement.

Trip circuit breaker (emergency stop)

Immediately halt matching AI operations for the organization (EU AI Act Article 14). Also exposed as the alias POST /api/v1/emergency-stop.

Identity comes from headers stamped by the auth middleware: X-Org-ID (falls back to X-Tenant-ID) selects the org; X-User-ID is required for the Article 14 audit trail (400 when missing). X-User-Email is recorded when present.

Enterprise only — community builds register no circuit-breaker routes (404).

header Parameters
Authorization
required
string
Example: Basic bXktb3JnOkFYT04tVjIteHh4

OAuth2-style Basic authentication header. Format: Basic base64(clientId:clientSecret)

  • clientId: Your organization identifier (required)
  • clientSecret: Authentication credential (optional for community mode)

Not required when DEPLOYMENT_MODE=community.

Request Body schema: application/json
required
scope
string
Default: "global"
Enum: "global" "tenant" "client" "policy"

Blast radius of the stop

scope_id
string

Required for non-global scopes (tenant/client/policy ID)

reason
string
Default: "manual"
Enum: "manual" "policy_violation" "risk_level" "error_rate"
comment
string

Free-text audit-trail comment

duration_minutes
integer

Auto-expire after N minutes; 0 or omitted = indefinite

Responses

Request samples

Content type
application/json
{
  • "scope": "global",
  • "scope_id": "string",
  • "reason": "manual",
  • "comment": "string",
  • "duration_minutes": 0
}

Response samples

Content type
application/json
{
  • "success": true,
  • "data": {
    }
}

Reset circuit breaker (release emergency stop)

Release an emergency stop and resume normal operations. Also exposed as the alias POST /api/v1/emergency-stop/release. Requires X-Org-ID (or X-Tenant-ID) and X-User-ID headers (400 when missing). Enterprise only.

header Parameters
Authorization
required
string
Example: Basic bXktb3JnOkFYT04tVjIteHh4

OAuth2-style Basic authentication header. Format: Basic base64(clientId:clientSecret)

  • clientId: Your organization identifier (required)
  • clientSecret: Authentication credential (optional for community mode)

Not required when DEPLOYMENT_MODE=community.

Request Body schema: application/json
required
scope
string
Default: "global"
Enum: "global" "tenant" "client" "policy"
scope_id
string
comment
string

Free-text audit-trail comment

Responses

Request samples

Content type
application/json
{
  • "scope": "global",
  • "scope_id": "string",
  • "comment": "string"
}

Response samples

Content type
application/json
{
  • "success": true,
  • "data": {
    }
}

Check whether a request would be allowed

Evaluates the caller's scope hierarchy (global → tenant → client → policy) and reports whether an open circuit would block the request. Read-only; does not mutate circuit state. Enterprise only.

header Parameters
Authorization
required
string
Example: Basic bXktb3JnOkFYT04tVjIteHh4

OAuth2-style Basic authentication header. Format: Basic base64(clientId:clientSecret)

  • clientId: Your organization identifier (required)
  • clientSecret: Authentication credential (optional for community mode)

Not required when DEPLOYMENT_MODE=community.

Request Body schema: application/json
required
tenant_id
string
client_id
string
policy_id
string

Responses

Request samples

Content type
application/json
{
  • "tenant_id": "string",
  • "client_id": "string",
  • "policy_id": "string"
}

Response samples

Content type
application/json
{
  • "success": true,
  • "data": {
    }
}

Emergency stop (alias of circuit-breaker trip)

Clearer Article 14 naming for POST /api/v1/circuit-breaker/trip — identical handler, request body, and responses. Enterprise only.

header Parameters
Authorization
required
string
Example: Basic bXktb3JnOkFYT04tVjIteHh4

OAuth2-style Basic authentication header. Format: Basic base64(clientId:clientSecret)

  • clientId: Your organization identifier (required)
  • clientSecret: Authentication credential (optional for community mode)

Not required when DEPLOYMENT_MODE=community.

Request Body schema: application/json
required
scope
string
Default: "global"
Enum: "global" "tenant" "client" "policy"

Blast radius of the stop

scope_id
string

Required for non-global scopes (tenant/client/policy ID)

reason
string
Default: "manual"
Enum: "manual" "policy_violation" "risk_level" "error_rate"
comment
string

Free-text audit-trail comment

duration_minutes
integer

Auto-expire after N minutes; 0 or omitted = indefinite

Responses

Request samples

Content type
application/json
{
  • "scope": "global",
  • "scope_id": "string",
  • "reason": "manual",
  • "comment": "string",
  • "duration_minutes": 0
}

Response samples

Content type
application/json
{
  • "success": false,
  • "error": "Invalid request body"
}

Release emergency stop (alias of circuit-breaker reset)

Clearer Article 14 naming for POST /api/v1/circuit-breaker/reset — identical handler, request body, and responses. Enterprise only.

header Parameters
Authorization
required
string
Example: Basic bXktb3JnOkFYT04tVjIteHh4

OAuth2-style Basic authentication header. Format: Basic base64(clientId:clientSecret)

  • clientId: Your organization identifier (required)
  • clientSecret: Authentication credential (optional for community mode)

Not required when DEPLOYMENT_MODE=community.

Request Body schema: application/json
required
scope
string
Default: "global"
Enum: "global" "tenant" "client" "policy"
scope_id
string
comment
string

Free-text audit-trail comment

Responses

Request samples

Content type
application/json
{
  • "scope": "global",
  • "scope_id": "string",
  • "comment": "string"
}

Response samples

Content type
application/json
{
  • "success": false,
  • "error": "Invalid request body"
}

Get circuit breaker status

Returns all active (open) circuits for the organization. Uses X-Org-ID header for org identification.

header Parameters
Authorization
required
string
Example: Basic bXktb3JnOkFYT04tVjIteHh4

OAuth2-style Basic authentication header. Format: Basic base64(clientId:clientSecret)

  • clientId: Your organization identifier (required)
  • clientSecret: Authentication credential (optional for community mode)

Not required when DEPLOYMENT_MODE=community.

Responses

Response samples

Content type
application/json
{
  • "success": true,
  • "data": {
    }
}

Get circuit breaker history

Returns circuit breaker trip/reset history for audit trail. Ordered by creation time descending.

query Parameters
limit
integer [ 1 .. 100 ]
Default: 50
header Parameters
Authorization
required
string
Example: Basic bXktb3JnOkFYT04tVjIteHh4

OAuth2-style Basic authentication header. Format: Basic base64(clientId:clientSecret)

  • clientId: Your organization identifier (required)
  • clientSecret: Authentication credential (optional for community mode)

Not required when DEPLOYMENT_MODE=community.

Responses

Response samples

Content type
application/json
{
  • "success": true,
  • "data": {
    }
}

Get circuit breaker config

Returns effective circuit breaker configuration. If tenant_id is provided, returns tenant-specific overrides merged with global defaults. Otherwise returns global defaults.

query Parameters
tenant_id
string

Optional tenant ID for tenant-specific config

header Parameters
Authorization
required
string
Example: Basic bXktb3JnOkFYT04tVjIteHh4

OAuth2-style Basic authentication header. Format: Basic base64(clientId:clientSecret)

  • clientId: Your organization identifier (required)
  • clientSecret: Authentication credential (optional for community mode)

Not required when DEPLOYMENT_MODE=community.

Responses

Response samples

Content type
application/json
{
  • "success": true,
  • "data": {
    }
}

Update per-tenant circuit breaker config

Creates or updates per-tenant circuit breaker threshold overrides. Null fields fall back to global defaults.

header Parameters
Authorization
required
string
Example: Basic bXktb3JnOkFYT04tVjIteHh4

OAuth2-style Basic authentication header. Format: Basic base64(clientId:clientSecret)

  • clientId: Your organization identifier (required)
  • clientSecret: Authentication credential (optional for community mode)

Not required when DEPLOYMENT_MODE=community.

Request Body schema: application/json
required
tenant_id
required
string
error_threshold
integer or null
violation_threshold
integer or null
window_seconds
integer or null
default_timeout_seconds
integer or null
max_timeout_seconds
integer or null
enable_auto_recovery
boolean or null

Responses

Request samples

Content type
application/json
{
  • "tenant_id": "string",
  • "error_threshold": 0,
  • "violation_threshold": 0,
  • "window_seconds": 0,
  • "default_timeout_seconds": 0,
  • "max_timeout_seconds": 0,
  • "enable_auto_recovery": true
}

Response samples

Content type
application/json
{
  • "success": false,
  • "error": "Invalid request body"
}

List notification configs

Returns all circuit breaker notification configs for the organization.

header Parameters
Authorization
required
string
Example: Basic bXktb3JnOkFYT04tVjIteHh4

OAuth2-style Basic authentication header. Format: Basic base64(clientId:clientSecret)

  • clientId: Your organization identifier (required)
  • clientSecret: Authentication credential (optional for community mode)

Not required when DEPLOYMENT_MODE=community.

Responses

Response samples

Content type
application/json
{
  • "success": true,
  • "data": {
    }
}

Create notification config

Create a notification channel for circuit breaker auto-trip events. Supports webhook (HMAC-signed), Slack (Block Kit), and PagerDuty (Events API v2).

header Parameters
Authorization
required
string
Example: Basic bXktb3JnOkFYT04tVjIteHh4

OAuth2-style Basic authentication header. Format: Basic base64(clientId:clientSecret)

  • clientId: Your organization identifier (required)
  • clientSecret: Authentication credential (optional for community mode)

Not required when DEPLOYMENT_MODE=community.

Request Body schema: application/json
required
type
required
string
Enum: "webhook" "slack" "pagerduty"
url
required
string

Webhook URL, Slack incoming webhook URL, or PagerDuty override URL

secret
string

HMAC secret for webhooks, or PagerDuty routing key

tenant_id
string

Optional tenant filter for notifications

active
boolean
Default: true

Responses

Request samples

Content type
application/json
{
  • "type": "webhook",
  • "url": "string",
  • "secret": "string",
  • "tenant_id": "string",
  • "active": true
}

Response samples

Content type
application/json
{
  • "success": false,
  • "error": "Invalid request body"
}

Update notification config

path Parameters
id
required
string
header Parameters
Authorization
required
string
Example: Basic bXktb3JnOkFYT04tVjIteHh4

OAuth2-style Basic authentication header. Format: Basic base64(clientId:clientSecret)

  • clientId: Your organization identifier (required)
  • clientSecret: Authentication credential (optional for community mode)

Not required when DEPLOYMENT_MODE=community.

Request Body schema: application/json
required
type
string
Enum: "webhook" "slack" "pagerduty"
url
string
secret
string
tenant_id
string
active
boolean

Responses

Request samples

Content type
application/json
{
  • "type": "webhook",
  • "url": "string",
  • "secret": "string",
  • "tenant_id": "string",
  • "active": true
}

Delete notification config

path Parameters
id
required
string
header Parameters
Authorization
required
string
Example: Basic bXktb3JnOkFYT04tVjIteHh4

OAuth2-style Basic authentication header. Format: Basic base64(clientId:clientSecret)

  • clientId: Your organization identifier (required)
  • clientSecret: Authentication credential (optional for community mode)

Not required when DEPLOYMENT_MODE=community.

Responses

OpenAI Compatible

OpenAI-compatible gateway endpoint (Issue #2351). Accepts standard OpenAI Chat Completions requests, runs AxonFlow policy checks, forwards to the upstream provider, records audit, and returns an OpenAI-compatible response. Customers change only baseURL in their OpenAI SDK setup.

OpenAI-compatible chat completions with policy enforcement

Accepts a standard OpenAI Chat Completions request, decides it with the ADR-065 decision plane (PRD v11 §1.1; #4092) - the shared policy engine's detectors are its input - forwards an allowed request to the upstream provider, records audit (tokens, cost, latency, policy decision), and returns an OpenAI-compatible response.

The route carries no per-user identity, so every request is decided for its client credential (Client). OpenAI's user request member is NOT honoured as an identity: it is free text the caller chooses, and a principal is never taken from it.

The caller passes their upstream provider API key via the X-Provider-Key header. AxonFlow auth (Basic Auth or community mode) is handled by the same apiAuthMiddleware as all other agent endpoints.

Streaming (stream: true) is not supported in this release and returns HTTP 400 with a clear error.

header Parameters
X-Provider-Key
required
string

Upstream LLM provider API key (e.g. OpenAI API key)

traceparent
string

W3C traceparent header for trace correlation

Request Body schema: application/json
required
model
required
string

ID of the model to use (e.g. gpt-4o, gpt-4o-mini).

required
Array of objects non-empty
temperature
number [ 0 .. 2 ]
top_p
number
max_tokens
integer
max_completion_tokens
integer
stream
boolean

Must be false or omitted. Streaming is not supported in this release; setting stream=true returns HTTP 400.

stop
any

Up to 4 stop sequences.

presence_penalty
number
frequency_penalty
number
user
string
response_format
object
seed
integer
tools
Array of objects
tool_choice
any

Tool choice configuration.

Responses

Request samples

Content type
application/json
{
  • "model": "gpt-4o",
  • "messages": [
    ],
  • "temperature": 0.7,
  • "max_tokens": 100
}

Response samples

Content type
application/json
{
  • "id": "chatcmpl-abc123",
  • "object": "chat.completion",
  • "created": 0,
  • "model": "string",
  • "choices": [
    ],
  • "usage": {
    },
  • "system_fingerprint": "string"
}

System Policies

System policy management (ADR-019), served at /api/v1/system-policies. Pattern-based enforcement rules for SQL injection detection, PII detection and similar checks, resolved across the system, organization and tenant tiers.

v11: writes to this family are refused by the legacy policy freeze. migrations/core/172 makes static_policies read-only to the application roles, and create, update, delete and the enabled toggle write that table. On a deployment whose connection is an application role (the agent's default) those writes are refused with 409 LEGACY_POLICY_WRITE_FROZEN, the answer the orchestrator gives for its own policy writes (see policy-api.yaml). Its error.code is that string, where the other errors on these routes carry the numeric status. Author policy through the typed authoring route, /api/v1/typed-policies in orchestrator-api.yaml. Reads, the pattern test, and the per-policy overrides - which are stored in their own table - are unaffected. A deployment whose connection may still write the table (the database owner; a property of the connection, not of AXONFLOW_DB_USE_APP_ROLE alone) is not bound by the revoke.

List policy overrides (canonical alias) Deprecated

Portal-facing alias of GET /api/v1/system-policies/overrides (deprecated spelling: GET /api/v1/static-policies/overrides): identical handler, parameters, and response.

This route itself is not deprecated and emits no Deprecation header.

query Parameters
include_expired
boolean
Default: false

Include expired overrides in results

header Parameters
Authorization
required
string
Example: Basic bXktb3JnOkFYT04tVjIteHh4

OAuth2-style Basic authentication header. Format: Basic base64(clientId:clientSecret)

  • clientId: Your organization identifier (required)
  • clientSecret: Authentication credential (optional for community mode)

Not required when DEPLOYMENT_MODE=community.

Responses

Response samples

Content type
application/json
{
  • "overrides": [
    ],
  • "count": 0
}

List static policies Deprecated

Returns static policies with three-tier hierarchy resolution:

  1. System policies - Managed by AxonFlow, immutable base
  2. Organization policies - Enterprise tier, organization-wide (Enterprise only)
  3. Tenant policies - Per-tenant customizations

v2.0.0 Categories (semantic naming):

  • security-sqli - SQL injection detection (was: sql_injection)
  • security-admin - Admin access protection (was: admin_access)
  • pii-global - Global PII patterns (was: pii_detection)
  • pii-us - US-specific PII (SSN, etc.)
  • pii-eu - EU-specific PII (GDPR)
  • pii-india - India-specific PII (Aadhaar, PAN)
  • custom - Tenant-created policies

Legacy category names are still accepted and automatically mapped.

Part of ADR-019: Unified Policy Management System.

query Parameters
page
integer >= 1
Default: 1

Page number (1-indexed)

page_size
integer [ 1 .. 100 ]
Default: 20

Number of policies per page

category
string
Enum: "security-sqli" "security-admin" "pii-global" "pii-us" "pii-eu" "pii-india" "custom" "sql_injection" "pii_detection" "dangerous_queries" "admin_access"

Filter by policy category. New categories use semantic naming. Legacy names (sql_injection, pii_detection, etc.) are still accepted.

tier
string
Enum: "system" "organization" "tenant"

Filter by policy tier

severity
string
Enum: "critical" "high" "medium" "low"

Filter by severity level

enabled
boolean

Filter by enabled status

header Parameters
Authorization
string

Basic auth credentials: Basic base64(clientId:clientSecret). Required in evaluation/enterprise mode. Optional in community mode (defaults to community tenant).

Responses

Response samples

Content type
application/json
{
  • "policies": [
    ],
  • "pagination": {
    }
}

Create static policy Deprecated

Creates a new static policy for the tenant.

Tier restrictions:

  • system tier: Cannot be created via API (managed by AxonFlow)
  • organization tier: Requires Enterprise license
  • tenant tier: Default, limited to 20 policies in Community mode

Part of ADR-019: Unified Policy Management System.

v11: on a deployment whose database connection cannot write static_policies (migrations/core/172), this route answers 409 LEGACY_POLICY_WRITE_FROZEN before the request body is read, whatever it contains, naming the typed authoring route. An owner-role deployment still creates.

header Parameters
Authorization
string

Basic auth credentials: Basic base64(clientId:clientSecret). Required in evaluation/enterprise mode. Optional in community mode (defaults to community tenant).

X-User-ID
string

User ID for audit trail

Request Body schema: application/json
required
name
required
string

Display name of the policy

description
string

Detailed policy description

category
required
string
Enum: "security-sqli" "security-admin" "pii-global" "pii-us" "pii-eu" "pii-india" "custom"

Policy category

tier
string
Default: "tenant"
Enum: "organization" "tenant"

Policy tier (system not allowed via API). Default is tenant.

pattern
required
string

Regex pattern for detection

action
required
string
Enum: "block" "require_approval" "redact" "warn" "log"

Action to take when pattern matches

severity
string
Enum: "critical" "high" "medium" "low"

Severity level

priority
integer
Default: 100

Priority order (lower = higher priority)

enabled
boolean
Default: true

Whether the policy is active

tags
Array of strings

Tags for categorization

Responses

Request samples

Content type
application/json
{
  • "name": "Custom Employee ID Detection",
  • "description": "Detects internal employee ID format",
  • "category": "custom",
  • "tier": "tenant",
  • "pattern": "EMP-[0-9]{6}",
  • "action": "warn",
  • "severity": "medium",
  • "enabled": true,
  • "tags": [
    ]
}

Response samples

Content type
application/json
{
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "policy_id": "sys_sqli_union_select",
  • "name": "UNION SELECT Detection",
  • "description": "Detects SQL injection attempts using UNION SELECT",
  • "category": "security-sqli",
  • "tier": "system",
  • "pattern": "(?i)\\bUNION\\s+(ALL\\s+)?SELECT\\b",
  • "severity": "critical",
  • "action": "block",
  • "enabled": true,
  • "priority": 1000,
  • "version": 1,
  • "has_override": true,
  • "override": {
    },
  • "tenant_id": "string",
  • "created_at": "2019-08-24T14:15:22Z",
  • "updated_at": "2019-08-24T14:15:22Z"
}

Get effective policies Deprecated

Returns all effective policies for a tenant with overrides applied.

This endpoint resolves the three-tier hierarchy:

  1. System policies (base)
  2. Organization overrides (if any)
  3. Tenant overrides (if any)

Used by the Customer Portal for the unified policy view.

header Parameters
Authorization
string

Basic auth credentials: Basic base64(clientId:clientSecret). Required in evaluation/enterprise mode. Optional in community mode (defaults to community tenant).

Responses

Response samples

Content type
application/json
{
  • "static": [
    ],
  • "tenant_id": "string",
  • "organization_id": "string",
  • "computed_at": "2019-08-24T14:15:22Z"
}

Test regex pattern Deprecated

Tests a regex pattern against input strings without creating a policy.

Useful for validating patterns before creating policies. Has a 5-second timeout to prevent ReDoS attacks.

Request Body schema: application/json
required
pattern
required
string

Regex pattern to test

input
string

Single input string to test (for backward compatibility)

inputs
Array of strings

Multiple input strings to test

Responses

Request samples

Content type
application/json
Example
{
  • "pattern": "\\b[0-9]{3}-[0-9]{2}-[0-9]{4}\\b",
  • "input": "My SSN is 123-45-6789"
}

Response samples

Content type
application/json
{
  • "valid": true,
  • "results": [
    ],
  • "error": "string"
}

List policy overrides Deprecated

Lists all policy overrides for a tenant.

Overrides allow Enterprise customers to modify system policy behavior (action, enabled status) without changing the underlying pattern.

query Parameters
include_expired
boolean
Default: false

Include expired overrides in results

header Parameters
Authorization
string

Basic auth credentials: Basic base64(clientId:clientSecret). Required in evaluation/enterprise mode. Optional in community mode (defaults to community tenant).

Responses

Response samples

Content type
application/json
{
  • "overrides": [
    ],
  • "count": 0
}

Get static policy by ID Deprecated

Returns a single static policy by its UUID.

The policy ID is the id field from the static_policies table, not the policy_id (human-readable identifier like 'sql_injection_union').

path Parameters
id
required
string <uuid>

Static policy UUID

header Parameters
Authorization
string

Basic auth credentials: Basic base64(clientId:clientSecret). Required in evaluation/enterprise mode. Optional in community mode (defaults to community tenant).

Responses

Response samples

Content type
application/json
{
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "policy_id": "sys_sqli_union_select",
  • "name": "UNION SELECT Detection",
  • "description": "Detects SQL injection attempts using UNION SELECT",
  • "category": "security-sqli",
  • "tier": "system",
  • "pattern": "(?i)\\bUNION\\s+(ALL\\s+)?SELECT\\b",
  • "severity": "critical",
  • "action": "block",
  • "enabled": true,
  • "priority": 1000,
  • "version": 1,
  • "has_override": true,
  • "override": {
    },
  • "tenant_id": "string",
  • "created_at": "2019-08-24T14:15:22Z",
  • "updated_at": "2019-08-24T14:15:22Z"
}

Update static policy Deprecated

Updates an existing static policy.

Restrictions:

  • System-tier policies cannot be modified (use overrides instead)
  • Pattern changes trigger version increment

v11: on a deployment whose database connection cannot write static_policies (migrations/core/172), this route answers 409 LEGACY_POLICY_WRITE_FROZEN before the request body is read and before the policy is looked up, whatever it contains, naming the typed authoring route. An owner-role deployment still updates.

path Parameters
id
required
string <uuid>

Static policy UUID

header Parameters
X-User-ID
string

User ID for audit trail

Request Body schema: application/json
required
name
string

Display name of the policy

description
string

Detailed policy description

pattern
string

Regex pattern (only for non-system policies)

action
string
Enum: "block" "require_approval" "redact" "warn" "log"
severity
string
Enum: "critical" "high" "medium" "low"
priority
integer
enabled
boolean
category
string
Enum: "security-sqli" "security-admin" "pii-global" "pii-us" "pii-eu" "pii-india" "custom"

Policy category. Updates can re-categorise non-system policies; system policies stay pinned to their seeded category.

tags
Array of strings

Responses

Request samples

Content type
application/json
{
  • "name": "string",
  • "description": "string",
  • "pattern": "string",
  • "action": "block",
  • "severity": "critical",
  • "priority": 0,
  • "enabled": true,
  • "category": "security-sqli",
  • "tags": [
    ]
}

Response samples

Content type
application/json
{
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "policy_id": "sys_sqli_union_select",
  • "name": "UNION SELECT Detection",
  • "description": "Detects SQL injection attempts using UNION SELECT",
  • "category": "security-sqli",
  • "tier": "system",
  • "pattern": "(?i)\\bUNION\\s+(ALL\\s+)?SELECT\\b",
  • "severity": "critical",
  • "action": "block",
  • "enabled": true,
  • "priority": 1000,
  • "version": 1,
  • "has_override": true,
  • "override": {
    },
  • "tenant_id": "string",
  • "created_at": "2019-08-24T14:15:22Z",
  • "updated_at": "2019-08-24T14:15:22Z"
}

Delete static policy Deprecated

Soft-deletes a static policy (sets deleted_at timestamp).

Restrictions:

  • System-tier policies cannot be deleted
path Parameters
id
required
string <uuid>

Static policy UUID

header Parameters
X-User-ID
string

User ID for audit trail

Responses

Response samples

Content type
application/json
{
  • "success": false,
  • "error": "string"
}

Toggle policy enabled status Deprecated

Toggles the enabled status of a policy.

Restrictions:

  • System-tier policies cannot be disabled via this endpoint (use overrides)

v11: on a deployment whose database connection cannot write static_policies (migrations/core/172), this route answers 409 LEGACY_POLICY_WRITE_FROZEN before the request body is read and before the policy is looked up, whatever it contains, naming the typed authoring route. An owner-role deployment still toggles.

path Parameters
id
required
string <uuid>

Static policy UUID

header Parameters
X-User-ID
string

User ID for audit trail

Request Body schema: application/json
required
enabled
required
boolean

New enabled status

Responses

Request samples

Content type
application/json
{
  • "enabled": true
}

Response samples

Content type
application/json
{
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "policy_id": "sys_sqli_union_select",
  • "name": "UNION SELECT Detection",
  • "description": "Detects SQL injection attempts using UNION SELECT",
  • "category": "security-sqli",
  • "tier": "system",
  • "pattern": "(?i)\\bUNION\\s+(ALL\\s+)?SELECT\\b",
  • "severity": "critical",
  • "action": "block",
  • "enabled": true,
  • "priority": 1000,
  • "version": 1,
  • "has_override": true,
  • "override": {
    },
  • "tenant_id": "string",
  • "created_at": "2019-08-24T14:15:22Z",
  • "updated_at": "2019-08-24T14:15:22Z"
}

Get policy version history Deprecated

Returns the version history for a policy.

Edition limits:

  • Community: Last 5 versions
  • Enterprise: Unlimited history
path Parameters
id
required
string <uuid>

Static policy UUID

header Parameters
Authorization
string

Basic auth credentials: Basic base64(clientId:clientSecret). Required in evaluation/enterprise mode. Optional in community mode (defaults to community tenant).

Responses

Response samples

Content type
application/json
{
  • "policy_id": "string",
  • "versions": [
    ],
  • "count": 0
}

Get active override for a policy Deprecated

Returns the active override for a single policy (404 when none). {id} may be the policy UUID or the human-readable slug - slugs are resolved to the canonical UUID before lookup.

path Parameters
id
required
string
header Parameters
Authorization
required
string
Example: Basic bXktb3JnOkFYT04tVjIteHh4

OAuth2-style Basic authentication header. Format: Basic base64(clientId:clientSecret)

  • clientId: Your organization identifier (required)
  • clientSecret: Authentication credential (optional for community mode)

Not required when DEPLOYMENT_MODE=community.

Responses

Response samples

Content type
application/json
{
  • "id": "string",
  • "policy_id": "string",
  • "policy_type": "static",
  • "tenant_id": "string",
  • "enabled_override": true,
  • "action_override": "block",
  • "override_reason": "string",
  • "expires_at": "2019-08-24T14:15:22Z",
  • "created_by": "string",
  • "created_at": "2019-08-24T14:15:22Z",
  • "updated_by": "string",
  • "updated_at": "2019-08-24T14:15:22Z"
}

Create policy override Deprecated

Retired in v11 (PRD v11 §1.5): a system control is enabled, disabled or re-actioned in the organization's typed document, in its system_controls section, through /api/v1/typed-policies. This route writes nothing and does not read a body: it answers 409 LEGACY_POLICY_WRITE_FROZEN to every authenticated caller, in every edition. The ADR-044 session override writes answer the same refusal since v11.0.0 (#4252); the override reads are unaffected.

path Parameters
id
required
string <uuid>

Static policy UUID to override

header Parameters
Authorization
string

Basic auth credentials: Basic base64(clientId:clientSecret). Required in evaluation/enterprise mode. Optional in community mode (defaults to community tenant).

X-User-ID
string

User ID for audit trail

Request Body schema: application/json
required
action_override
string
Enum: "block" "require_approval" "redact" "warn" "log"

Override the policy action

enabled_override
boolean

Override the enabled status

override_reason
required
string

Required explanation for audit trail

expires_at
string <date-time>

Optional expiration for the override

Responses

Request samples

Content type
application/json
Example
{
  • "enabled_override": false,
  • "override_reason": "False positive rate too high for this tenant",
  • "expires_at": "2025-06-01T00:00:00Z"
}

Response samples

Content type
application/json
{
  • "success": false,
  • "error": "Authentication required: provide Authorization header with Basic auth (clientId:clientSecret)"
}

Delete policy override Deprecated

Retired in v11 (PRD v11 §1.5): a system control is enabled, disabled or re-actioned in the organization's typed document, in its system_controls section, through /api/v1/typed-policies. This route writes nothing and does not read a body: it answers 409 LEGACY_POLICY_WRITE_FROZEN to every authenticated caller, in every edition. The ADR-044 session override writes answer the same refusal since v11.0.0 (#4252); the override reads are unaffected.

path Parameters
id
required
string <uuid>

Static policy UUID

header Parameters
Authorization
string

Basic auth credentials: Basic base64(clientId:clientSecret). Required in evaluation/enterprise mode. Optional in community mode (defaults to community tenant).

X-User-ID
string

User ID for audit trail

Responses

Response samples

Content type
application/json
{
  • "success": false,
  • "error": "Authentication required: provide Authorization header with Basic auth (clientId:clientSecret)"
}

Static Policies

DEPRECATED spelling of System Policies, served at /api/v1/static-policies. Every operation is the same handler as its /api/v1/system-policies counterpart and returns the same status code and body.

In v11 BOTH spellings are the deprecated export surface (PRD §1.11): reads are served, and every response carries Link: </api/v1/typed-policies>; rel="successor-version" and X-AxonFlow-Removed-In: v11.1, plus an RFC 9745 Deprecation: @<epoch> from the v11.0.0 tag. v11.1 removes both spellings; there is no Sunset header until that release has a date. The v11 write refusal described under System Policies applies to these paths identically.

List static policies Deprecated

Returns static policies with three-tier hierarchy resolution:

  1. System policies - Managed by AxonFlow, immutable base
  2. Organization policies - Enterprise tier, organization-wide (Enterprise only)
  3. Tenant policies - Per-tenant customizations

v2.0.0 Categories (semantic naming):

  • security-sqli - SQL injection detection (was: sql_injection)
  • security-admin - Admin access protection (was: admin_access)
  • pii-global - Global PII patterns (was: pii_detection)
  • pii-us - US-specific PII (SSN, etc.)
  • pii-eu - EU-specific PII (GDPR)
  • pii-india - India-specific PII (Aadhaar, PAN)
  • custom - Tenant-created policies

Legacy category names are still accepted and automatically mapped.

Part of ADR-019: Unified Policy Management System.

query Parameters
page
integer >= 1
Default: 1

Page number (1-indexed)

page_size
integer [ 1 .. 100 ]
Default: 20

Number of policies per page

category
string
Enum: "security-sqli" "security-admin" "pii-global" "pii-us" "pii-eu" "pii-india" "custom" "sql_injection" "pii_detection" "dangerous_queries" "admin_access"

Filter by policy category. New categories use semantic naming. Legacy names (sql_injection, pii_detection, etc.) are still accepted.

tier
string
Enum: "system" "organization" "tenant"

Filter by policy tier

severity
string
Enum: "critical" "high" "medium" "low"

Filter by severity level

enabled
boolean

Filter by enabled status

header Parameters
Authorization
string

Basic auth credentials: Basic base64(clientId:clientSecret). Required in evaluation/enterprise mode. Optional in community mode (defaults to community tenant).

Responses

Response samples

Content type
application/json
{
  • "policies": [
    ],
  • "pagination": {
    }
}

Create static policy Deprecated

Creates a new static policy for the tenant.

Tier restrictions:

  • system tier: Cannot be created via API (managed by AxonFlow)
  • organization tier: Requires Enterprise license
  • tenant tier: Default, limited to 20 policies in Community mode

Part of ADR-019: Unified Policy Management System.

v11: on a deployment whose database connection cannot write static_policies (migrations/core/172), this route answers 409 LEGACY_POLICY_WRITE_FROZEN before the request body is read, whatever it contains, naming the typed authoring route. An owner-role deployment still creates.

header Parameters
Authorization
string

Basic auth credentials: Basic base64(clientId:clientSecret). Required in evaluation/enterprise mode. Optional in community mode (defaults to community tenant).

X-User-ID
string

User ID for audit trail

Request Body schema: application/json
required
name
required
string

Display name of the policy

description
string

Detailed policy description

category
required
string
Enum: "security-sqli" "security-admin" "pii-global" "pii-us" "pii-eu" "pii-india" "custom"

Policy category

tier
string
Default: "tenant"
Enum: "organization" "tenant"

Policy tier (system not allowed via API). Default is tenant.

pattern
required
string

Regex pattern for detection

action
required
string
Enum: "block" "require_approval" "redact" "warn" "log"

Action to take when pattern matches

severity
string
Enum: "critical" "high" "medium" "low"

Severity level

priority
integer
Default: 100

Priority order (lower = higher priority)

enabled
boolean
Default: true

Whether the policy is active

tags
Array of strings

Tags for categorization

Responses

Request samples

Content type
application/json
{
  • "name": "Custom Employee ID Detection",
  • "description": "Detects internal employee ID format",
  • "category": "custom",
  • "tier": "tenant",
  • "pattern": "EMP-[0-9]{6}",
  • "action": "warn",
  • "severity": "medium",
  • "enabled": true,
  • "tags": [
    ]
}

Response samples

Content type
application/json
{
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "policy_id": "sys_sqli_union_select",
  • "name": "UNION SELECT Detection",
  • "description": "Detects SQL injection attempts using UNION SELECT",
  • "category": "security-sqli",
  • "tier": "system",
  • "pattern": "(?i)\\bUNION\\s+(ALL\\s+)?SELECT\\b",
  • "severity": "critical",
  • "action": "block",
  • "enabled": true,
  • "priority": 1000,
  • "version": 1,
  • "has_override": true,
  • "override": {
    },
  • "tenant_id": "string",
  • "created_at": "2019-08-24T14:15:22Z",
  • "updated_at": "2019-08-24T14:15:22Z"
}

Get effective policies Deprecated

Returns all effective policies for a tenant with overrides applied.

This endpoint resolves the three-tier hierarchy:

  1. System policies (base)
  2. Organization overrides (if any)
  3. Tenant overrides (if any)

Used by the Customer Portal for the unified policy view.

header Parameters
Authorization
string

Basic auth credentials: Basic base64(clientId:clientSecret). Required in evaluation/enterprise mode. Optional in community mode (defaults to community tenant).

Responses

Response samples

Content type
application/json
{
  • "static": [
    ],
  • "tenant_id": "string",
  • "organization_id": "string",
  • "computed_at": "2019-08-24T14:15:22Z"
}

Test regex pattern Deprecated

Tests a regex pattern against input strings without creating a policy.

Useful for validating patterns before creating policies. Has a 5-second timeout to prevent ReDoS attacks.

The pattern is compiled as written. The engine compiles a stored pattern in the SQL-injection and destructive-command categories case-insensitively, so for those categories prefix (?i) to test what the engine matches.

Request Body schema: application/json
required
pattern
required
string

Regex pattern to test

input
string

Single input string to test (for backward compatibility)

inputs
Array of strings

Multiple input strings to test

Responses

Request samples

Content type
application/json
Example
{
  • "pattern": "\\b[0-9]{3}-[0-9]{2}-[0-9]{4}\\b",
  • "input": "My SSN is 123-45-6789"
}

Response samples

Content type
application/json
{
  • "valid": true,
  • "results": [
    ],
  • "error": "string"
}

List policy overrides Deprecated

Lists all policy overrides for a tenant.

Overrides allow Enterprise customers to modify system policy behavior (action, enabled status) without changing the underlying pattern.

query Parameters
include_expired
boolean
Default: false

Include expired overrides in results

header Parameters
Authorization
string

Basic auth credentials: Basic base64(clientId:clientSecret). Required in evaluation/enterprise mode. Optional in community mode (defaults to community tenant).

Responses

Response samples

Content type
application/json
{
  • "overrides": [
    ],
  • "count": 0
}

Get static policy by ID Deprecated

Returns a single static policy by its UUID.

The policy ID is the id field from the static_policies table, not the policy_id (human-readable identifier like 'sql_injection_union').

path Parameters
id
required
string <uuid>

Static policy UUID

header Parameters
Authorization
string

Basic auth credentials: Basic base64(clientId:clientSecret). Required in evaluation/enterprise mode. Optional in community mode (defaults to community tenant).

Responses

Response samples

Content type
application/json
{
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "policy_id": "sys_sqli_union_select",
  • "name": "UNION SELECT Detection",
  • "description": "Detects SQL injection attempts using UNION SELECT",
  • "category": "security-sqli",
  • "tier": "system",
  • "pattern": "(?i)\\bUNION\\s+(ALL\\s+)?SELECT\\b",
  • "severity": "critical",
  • "action": "block",
  • "enabled": true,
  • "priority": 1000,
  • "version": 1,
  • "has_override": true,
  • "override": {
    },
  • "tenant_id": "string",
  • "created_at": "2019-08-24T14:15:22Z",
  • "updated_at": "2019-08-24T14:15:22Z"
}

Update static policy Deprecated

Updates an existing static policy.

Restrictions:

  • System-tier policies cannot be modified (use overrides instead)
  • Pattern changes trigger version increment

v11: on a deployment whose database connection cannot write static_policies (migrations/core/172), this route answers 409 LEGACY_POLICY_WRITE_FROZEN before the request body is read and before the policy is looked up, whatever it contains, naming the typed authoring route. An owner-role deployment still updates.

path Parameters
id
required
string <uuid>

Static policy UUID

header Parameters
X-User-ID
string

User ID for audit trail

Request Body schema: application/json
required
name
string

Display name of the policy

description
string

Detailed policy description

pattern
string

Regex pattern (only for non-system policies)

action
string
Enum: "block" "require_approval" "redact" "warn" "log"
severity
string
Enum: "critical" "high" "medium" "low"
priority
integer
enabled
boolean
category
string
Enum: "security-sqli" "security-admin" "pii-global" "pii-us" "pii-eu" "pii-india" "custom"

Policy category. Updates can re-categorise non-system policies; system policies stay pinned to their seeded category.

tags
Array of strings

Responses

Request samples

Content type
application/json
{
  • "name": "string",
  • "description": "string",
  • "pattern": "string",
  • "action": "block",
  • "severity": "critical",
  • "priority": 0,
  • "enabled": true,
  • "category": "security-sqli",
  • "tags": [
    ]
}

Response samples

Content type
application/json
{
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "policy_id": "sys_sqli_union_select",
  • "name": "UNION SELECT Detection",
  • "description": "Detects SQL injection attempts using UNION SELECT",
  • "category": "security-sqli",
  • "tier": "system",
  • "pattern": "(?i)\\bUNION\\s+(ALL\\s+)?SELECT\\b",
  • "severity": "critical",
  • "action": "block",
  • "enabled": true,
  • "priority": 1000,
  • "version": 1,
  • "has_override": true,
  • "override": {
    },
  • "tenant_id": "string",
  • "created_at": "2019-08-24T14:15:22Z",
  • "updated_at": "2019-08-24T14:15:22Z"
}

Delete static policy Deprecated

Soft-deletes a static policy (sets deleted_at timestamp).

Restrictions:

  • System-tier policies cannot be deleted
path Parameters
id
required
string <uuid>

Static policy UUID

header Parameters
X-User-ID
string

User ID for audit trail

Responses

Response samples

Content type
application/json
{
  • "success": false,
  • "error": "string"
}

Toggle policy enabled status Deprecated

Toggles the enabled status of a policy.

Restrictions:

  • System-tier policies cannot be disabled via this endpoint (use overrides)

v11: on a deployment whose database connection cannot write static_policies (migrations/core/172), this route answers 409 LEGACY_POLICY_WRITE_FROZEN before the request body is read and before the policy is looked up, whatever it contains, naming the typed authoring route. An owner-role deployment still toggles.

path Parameters
id
required
string <uuid>

Static policy UUID

header Parameters
X-User-ID
string

User ID for audit trail

Request Body schema: application/json
required
enabled
required
boolean

New enabled status

Responses

Request samples

Content type
application/json
{
  • "enabled": true
}

Response samples

Content type
application/json
{
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "policy_id": "sys_sqli_union_select",
  • "name": "UNION SELECT Detection",
  • "description": "Detects SQL injection attempts using UNION SELECT",
  • "category": "security-sqli",
  • "tier": "system",
  • "pattern": "(?i)\\bUNION\\s+(ALL\\s+)?SELECT\\b",
  • "severity": "critical",
  • "action": "block",
  • "enabled": true,
  • "priority": 1000,
  • "version": 1,
  • "has_override": true,
  • "override": {
    },
  • "tenant_id": "string",
  • "created_at": "2019-08-24T14:15:22Z",
  • "updated_at": "2019-08-24T14:15:22Z"
}

Get policy version history Deprecated

Returns the version history for a policy.

Edition limits:

  • Community: Last 5 versions
  • Enterprise: Unlimited history
path Parameters
id
required
string <uuid>

Static policy UUID

header Parameters
Authorization
string

Basic auth credentials: Basic base64(clientId:clientSecret). Required in evaluation/enterprise mode. Optional in community mode (defaults to community tenant).

Responses

Response samples

Content type
application/json
{
  • "policy_id": "string",
  • "versions": [
    ],
  • "count": 0
}

Get active override for a policy Deprecated

Returns the active override for a single policy (404 when none). {id} may be the policy UUID or the human-readable slug - slugs are resolved to the canonical UUID before lookup.

path Parameters
id
required
string
header Parameters
Authorization
required
string
Example: Basic bXktb3JnOkFYT04tVjIteHh4

OAuth2-style Basic authentication header. Format: Basic base64(clientId:clientSecret)

  • clientId: Your organization identifier (required)
  • clientSecret: Authentication credential (optional for community mode)

Not required when DEPLOYMENT_MODE=community.

Responses

Response samples

Content type
application/json
{
  • "id": "string",
  • "policy_id": "string",
  • "policy_type": "static",
  • "tenant_id": "string",
  • "enabled_override": true,
  • "action_override": "block",
  • "override_reason": "string",
  • "expires_at": "2019-08-24T14:15:22Z",
  • "created_by": "string",
  • "created_at": "2019-08-24T14:15:22Z",
  • "updated_by": "string",
  • "updated_at": "2019-08-24T14:15:22Z"
}

Create policy override Deprecated

Retired in v11 (PRD v11 §1.5): a system control is enabled, disabled or re-actioned in the organization's typed document, in its system_controls section, through /api/v1/typed-policies. This route writes nothing and does not read a body: it answers 409 LEGACY_POLICY_WRITE_FROZEN to every authenticated caller, in every edition. The ADR-044 session override writes answer the same refusal since v11.0.0 (#4252); the override reads are unaffected.

path Parameters
id
required
string <uuid>

Static policy UUID to override

header Parameters
Authorization
string

Basic auth credentials: Basic base64(clientId:clientSecret). Required in evaluation/enterprise mode. Optional in community mode (defaults to community tenant).

X-User-ID
string

User ID for audit trail

Request Body schema: application/json
required
action_override
string
Enum: "block" "require_approval" "redact" "warn" "log"

Override the policy action

enabled_override
boolean

Override the enabled status

override_reason
required
string

Required explanation for audit trail

expires_at
string <date-time>

Optional expiration for the override

Responses

Request samples

Content type
application/json
Example
{
  • "enabled_override": false,
  • "override_reason": "False positive rate too high for this tenant",
  • "expires_at": "2025-06-01T00:00:00Z"
}

Response samples

Content type
application/json
{
  • "success": false,
  • "error": "Authentication required: provide Authorization header with Basic auth (clientId:clientSecret)"
}

Delete policy override Deprecated

Retired in v11 (PRD v11 §1.5): a system control is enabled, disabled or re-actioned in the organization's typed document, in its system_controls section, through /api/v1/typed-policies. This route writes nothing and does not read a body: it answers 409 LEGACY_POLICY_WRITE_FROZEN to every authenticated caller, in every edition. The ADR-044 session override writes answer the same refusal since v11.0.0 (#4252); the override reads are unaffected.

path Parameters
id
required
string <uuid>

Static policy UUID

header Parameters
Authorization
string

Basic auth credentials: Basic base64(clientId:clientSecret). Required in evaluation/enterprise mode. Optional in community mode (defaults to community tenant).

X-User-ID
string

User ID for audit trail

Responses

Response samples

Content type
application/json
{
  • "success": false,
  • "error": "Authentication required: provide Authorization header with Basic auth (clientId:clientSecret)"
}

Audit Verification

Non-repudiation verification of the signed decision chain (#2722). Read-only endpoints that re-verify per-record Ed25519 signatures and the prev_hash linkage of a tenant's decision records, and publish the current public signing key for offline verification. These are not Policy Enforcement Points (no decision-engine call); they are org-scoped via the authenticated request context and read under RLS, so a caller can only verify chains/records belonging to its own organization. Available in any deployment mode once a usage database is configured; signatures verify only when an AXONFLOW_AUDIT_SIGNING_KEY is set (otherwise records are hash-chained but reported as unsigned).

Verify a decision chain

Re-verifies an entire decision chain: the prev_hash linkage across all of its records (ordering / completeness) and every per-record Ed25519 signature (authorship). Read-only; never mutates the chain.

The chain is resolved by id only within the authenticated caller's organization (RLS-scoped); the org is taken from the request credentials, never from a path or query parameter. chainID is the decision id (a UUID).

Inspect authorship_proven for the strong non-repudiation claim (every record signed and all signatures + linkage verify). valid only means no integrity violation was detected and can be true for a chain with zero signed records, so do not gate non-repudiation on valid alone.

Authority (#2914). Authentication alone is not enough: this route requires COMPLIANCE READ AUTHORITY over the organization. Present a validated per-user token (X-User-Token, or Authorization: Bearer) whose role is admin, owner or policy_admin, or call from an internal service asserting X-Axonflow-Admin-Authority: true. A Community-mode deployment is exempt: it has no authentication and resolves every caller to one local operator. Anything else is 403.

Community SaaS (try.getaxonflow.com) refuses these routes, by design. The hosted evaluation stack runs with authentication enabled, so the Community-mode exemption above does not apply to it, and its evaluator accounts hold no entitled role. Verification there is a 403. Granting evaluators access would widen, on a public shared stack, the exact exposure this change closes. Verify audit records on a deployment you operate.

path Parameters
chainID
required
string <uuid>

Decision chain id (the decision UUID)

header Parameters
Authorization
required
string
Example: Basic bXktb3JnOkFYT04tVjIteHh4

OAuth2-style Basic authentication header. Format: Basic base64(clientId:clientSecret)

  • clientId: Your organization identifier (required)
  • clientSecret: Authentication credential (optional for community mode)

Not required when DEPLOYMENT_MODE=community.

Responses

Response samples

Content type
application/json
{
  • "chain_id": "01c3b16e-4d9b-4398-a3ec-0a1f8f0bb259",
  • "org_id": "string",
  • "total_records": 0,
  • "valid": true,
  • "authorship_proven": true,
  • "linkage_valid": true,
  • "signatures_valid": true,
  • "signed_records": 0,
  • "unsigned_records": 0,
  • "first_broken_seq": 0,
  • "first_broken_record_id": "string",
  • "break_reason": "string",
  • "signing_key_id": "string",
  • "public_key": "string",
  • "verified_at": "2019-08-24T14:15:22Z"
}

Verify a single decision record

Verifies ONE decision record standalone, proving its authorship from the record alone without walking the rest of the chain. Read-only.

The response republishes the recomputed verification material so the result is independently checkable offline: digest_preimage_b64 is the exact byte string that SHA-256-hashes to record_digest; an auditor can base64-decode it, hash it, confirm it equals record_digest, rebuild it from the raw record fields, and then run ed25519.Verify(public_key, []byte(chain_hash), base64decode(record_signature)), trusting neither this endpoint nor its digest.

The record is resolved by id only within the authenticated caller's organization (RLS-scoped). recordID is the per-record UUID assigned at signing time (distinct from the chain id).

Authority (#2914). Authentication alone is not enough: this route requires COMPLIANCE READ AUTHORITY over the organization. Present a validated per-user token (X-User-Token, or Authorization: Bearer) whose role is admin, owner or policy_admin, or call from an internal service asserting X-Axonflow-Admin-Authority: true. A Community-mode deployment is exempt: it has no authentication and resolves every caller to one local operator. Anything else is 403.

Community SaaS (try.getaxonflow.com) refuses these routes, by design. The hosted evaluation stack runs with authentication enabled, so the Community-mode exemption above does not apply to it, and its evaluator accounts hold no entitled role. Verification there is a 403. Granting evaluators access would widen, on a public shared stack, the exact exposure this change closes. Verify audit records on a deployment you operate.

path Parameters
recordID
required
string <uuid>

Decision record id (the per-record UUID)

header Parameters
Authorization
required
string
Example: Basic bXktb3JnOkFYT04tVjIteHh4

OAuth2-style Basic authentication header. Format: Basic base64(clientId:clientSecret)

  • clientId: Your organization identifier (required)
  • clientSecret: Authentication credential (optional for community mode)

Not required when DEPLOYMENT_MODE=community.

Responses

Response samples

Content type
application/json
{
  • "record_id": "8bf519b6-a3e0-49d2-8e42-039542d9a489",
  • "chain_id": "01c3b16e-4d9b-4398-a3ec-0a1f8f0bb259",
  • "org_id": "string",
  • "chain_seq": 0,
  • "signed": true,
  • "signature_valid": true,
  • "valid": true,
  • "reason": "string",
  • "digest_preimage_b64": "string",
  • "record_digest": "string",
  • "prev_hash": "string",
  • "chain_hash": "string",
  • "record_signature": "string",
  • "signing_key_id": "string",
  • "public_key": "string",
  • "verified_at": "2019-08-24T14:15:22Z"
}

Publish the current public signing key

Returns the current public Ed25519 verification key so an external auditor can re-verify any record's signature offline. Read-only.

When no signing key is configured, configured is false and public_key is empty: records are hash-chained but unsigned, and the verify endpoints report that honestly.

Authority (#2914). Authentication alone is not enough: this route requires COMPLIANCE READ AUTHORITY over the organization. Present a validated per-user token (X-User-Token, or Authorization: Bearer) whose role is admin, owner or policy_admin, or call from an internal service asserting X-Axonflow-Admin-Authority: true. A Community-mode deployment is exempt: it has no authentication and resolves every caller to one local operator. Anything else is 403.

Community SaaS (try.getaxonflow.com) refuses these routes, by design. The hosted evaluation stack runs with authentication enabled, so the Community-mode exemption above does not apply to it, and its evaluator accounts hold no entitled role. Verification there is a 403. Granting evaluators access would widen, on a public shared stack, the exact exposure this change closes. Verify audit records on a deployment you operate.

header Parameters
Authorization
required
string
Example: Basic bXktb3JnOkFYT04tVjIteHh4

OAuth2-style Basic authentication header. Format: Basic base64(clientId:clientSecret)

  • clientId: Your organization identifier (required)
  • clientSecret: Authentication credential (optional for community mode)

Not required when DEPLOYMENT_MODE=community.

Responses

Response samples

Content type
application/json
{
  • "algorithm": "ed25519",
  • "signing_key_id": "string",
  • "public_key": "string",
  • "configured": true,
  • "verification_note": "string"
}

MCP Server

Streamable-HTTP MCP server (spec 2025-06-18) exposing AxonFlow governance as MCP tools (check_policy, check_output, audit_tool_call, list_policies, get_policy_stats, explain_decision + Pro tools). Consumed by the Claude Code / Cursor / Codex plugins and any MCP client. Authentication is HTTP Basic (org:license-key) — NOT OAuth; the /.well-known/oauth-* discovery paths deliberately return an advisory 404 saying so.

OAuth protected-resource metadata (always 404, by design)

Always answers 404 with an OAuth-shaped JSON error stating that this server uses HTTP Basic authentication. No authorization server is advertised. Any path under this prefix answers identically.

Responses

Response samples

Content type
application/json
{
  • "error": "oauth_not_supported",
  • "error_description": "AxonFlow's MCP server uses HTTP Basic authentication (base64(org_id:license_key)), not OAuth. Set AXONFLOW_ENDPOINT and AXONFLOW_AUTH in the environment that launches your MCP client."
}

OAuth authorization-server metadata (always 404, by design)

Always answers 404 with an OAuth-shaped JSON error stating that this server uses HTTP Basic authentication. Any path under this prefix answers identically.

Responses

Response samples

Content type
application/json
{
  • "error": "oauth_not_supported",
  • "error_description": "AxonFlow's MCP server uses HTTP Basic authentication (base64(org_id:license_key)), not OAuth. Set AXONFLOW_ENDPOINT and AXONFLOW_AUTH in the environment that launches your MCP client."
}

MCP JSON-RPC endpoint

Single Streamable-HTTP endpoint for the built-in MCP server. Accepts MCP JSON-RPC 2.0 messages (initialize, tools/list, tools/call, …) and returns JSON-RPC responses. Governance tools exposed: check_policy, check_output, audit_tool_call, list_policies, get_policy_stats, explain_decision, plus Pro-tier tools.

Authentication: HTTP Basic org:license-key on every request. An Enterprise deployment MAY additionally send a per-user token in X-User-Token (ADR-043/044). It is optional unless the organization's require_user_token posture demands one (see BasicAuth).

Governance segments no longer gate check_policy or check_output (they did from #3430, refusing with blocked_by: "segment_identity_unresolved" or "segment_resolution_failed"). Neither tool consults segments: each is decided by the anchored engine, which reads none (PRD v11 §1.1, §1.2), so a segment resolution that would fail changes nothing.

Two identity rules are narrower than an operator usually expects, and both are deliberate:

  • X-User-Email does not substitute for a validated per-user token, even when AXONFLOW_TRUST_IDENTITY_HEADERS is on. Under the organization's require_user_token posture, a caller without a validated token is refused before the header can supply an identity. The header keeps its attribution role; the ADR-044 override writes answer the freeze from v11.0.0 (#4252).
  • A shared synthetic identity never holds a per-user session override. ADR-044 overrides are scoped to (tenant, user, policy), so an override created under an identity many callers share would flip deny to allow for every one of them (#2896). create_override refuses such a session for its identity first (every other session is answered LEGACY_POLICY_WRITE_FROZEN from v11.0.0, #4252), and no override is offered to it; its audit rows still carry the identity. The census is IsSharedSyntheticIdentity in platform/shared/identity: the reserved axonflow.local and axonflow.internal addresses, the MCP client pseudo-identity prefix, and the Community-SaaS evaluator [email protected]; in Community mode the local-dev identity is exempt. Token minting validates only that the subject contains @, so a token for such an identity validates, and check_policy and check_output accept it like any other validated token.

The Community SaaS per-minute limit and daily quota are answered with HTTP 429, a Retry-After header, and the RateLimitEnvelope as JSON text in result.content[0].text, with result.isError: true (#4261; before it, the same result came with a 200). The per-minute limit answers limit_type: per_minute, window minute, resets_at one minute out and Retry-After: 60; the daily quota answers limit_type: daily_quota, window daily_utc, resetting at midnight UTC. A credential refused by the pre-credential per-minute limiter gets the same per-minute answer, with an empty tier because the tier is not resolved yet, instead of a 401. The tools/call tier gates (feature_pro_only, active_policies, hitl_approvals_window) answer the same result shape with a 200.

JSON-RPC error codes: -32001 is the one application code, an authentication failure, sent with HTTP 401 and a WWW-Authenticate: Basic challenge. The rest are the JSON-RPC 2.0 standard codes: -32700 (parse error) with HTTP 400, -32600 (invalid request) with HTTP 400, or 415 when the Content-Type is not application/json, and -32601 (method not found) and -32602 (invalid params) with a 200.

The JSON-RPC check_output tool result DOES include redacted_message — unlike the standalone REST /api/v1/mcp/check-output endpoint (#2870).

header Parameters
Authorization
required
string
Example: Basic bXktb3JnOkFYT04tVjIteHh4

OAuth2-style Basic authentication header. Format: Basic base64(clientId:clientSecret)

  • clientId: Your organization identifier (required)
  • clientSecret: Authentication credential (optional for community mode)

Not required when DEPLOYMENT_MODE=community.

Request Body schema: application/json
required
jsonrpc
string
Value: "2.0"
id
any

Request ID (absent for notifications)

method
string
object

Responses

Request samples

Content type
application/json
{
  • "jsonrpc": "2.0",
  • "id": null,
  • "method": "tools/call",
  • "params": { }
}

Response samples

Content type
application/json
{ }

Not supported (405)

The MCP server does not offer a server-initiated SSE stream; GET always returns 405 Method Not Allowed.

Responses

Terminate MCP session

Terminates the MCP session identified by the Mcp-Session-Id header.

header Parameters
Authorization
required
string
Example: Basic bXktb3JnOkFYT04tVjIteHh4

OAuth2-style Basic authentication header. Format: Basic base64(clientId:clientSecret)

  • clientId: Your organization identifier (required)
  • clientSecret: Authentication credential (optional for community mode)

Not required when DEPLOYMENT_MODE=community.

Mcp-Session-Id
string

Responses

Response samples

Content type
application/json
{
  • "success": false,
  • "error": "Authentication required: provide Authorization header with Basic auth (clientId:clientSecret)"
}

OTLP Ingest

OpenTelemetry OTLP/HTTP ingest for Claude Code (cowork) telemetry (#2832). Enterprise only — community builds mount the routes but return 501. Org/tenant identity always comes from the authenticated license, never from OTLP resource attributes.

OTLP metrics ingest

OTLP/HTTP ExportMetricsServiceRequest ingest for Claude Code telemetry. Content types: application/x-protobuf (default when the header is empty), application/protobuf, or application/json; anything else returns 415. Success returns 200 with an OTLP ExportMetricsServiceResponse in the request's content type.

Enterprise only — community builds return 501 with {"error": {"code", "message"}}. Org/tenant comes from the authenticated license (Basic auth), never from OTLP resource attributes.

header Parameters
Authorization
required
string
Example: Basic bXktb3JnOkFYT04tVjIteHh4

OAuth2-style Basic authentication header. Format: Basic base64(clientId:clientSecret)

  • clientId: Your organization identifier (required)
  • clientSecret: Authentication credential (optional for community mode)

Not required when DEPLOYMENT_MODE=community.

Request Body schema:
required
string <binary>

Responses

Request samples

Content type
No sample

Response samples

Content type
application/json
{
  • "success": false,
  • "error": "Authentication required: provide Authorization header with Basic auth (clientId:clientSecret)"
}

OTLP logs ingest

OTLP/HTTP ExportLogsServiceRequest ingest for Claude Code telemetry. Same content-type, auth, edition, and error semantics as POST /v1/metrics.

header Parameters
Authorization
required
string
Example: Basic bXktb3JnOkFYT04tVjIteHh4

OAuth2-style Basic authentication header. Format: Basic base64(clientId:clientSecret)

  • clientId: Your organization identifier (required)
  • clientSecret: Authentication credential (optional for community mode)

Not required when DEPLOYMENT_MODE=community.

Request Body schema:
required
string <binary>

Responses

Request samples

Content type
No sample

Response samples

Content type
application/json
{
  • "success": false,
  • "error": "Authentication required: provide Authorization header with Basic auth (clientId:clientSecret)"
}

AuthZEN

AuthZEN-native authorization decision

The AuthZEN-native authorization surface (ADR-065 compatibility plan, issue #3603). A Policy Enforcement Point sends a subject / action / resource / context evaluation and receives an AuthZEN decision.

This endpoint is an ADAPTER over the same evaluation that serves POST /api/v1/decide. It is not a second policy engine. Through v10.x the verdict is produced by today's evaluator; at v11 the engine behind this route changes to the ADR-065 Policy Decision Point with no wire change, so an integration written against this surface migrates once rather than twice. POST /api/v1/decide is unchanged and remains wire-stable through all of v11.

One route, both shapes. The body is the AuthZEN envelope, which carries exactly one of evaluation (singular) or evaluations (plural). Presence is decided on the key set, so {"evaluation": {...}, "evaluations": null} carries both declared members and is malformed.

A plural envelope returns one decision, not a list. Its entries are preconditions of a single operation, so they meet: one denied entry denies the operation. A plural entry inherits any member it omits from the envelope's shared base.

Every construct is mapped or refused; nothing is ignored. A request carrying data this surface cannot evaluate -- caller-supplied properties, an unrecognised context member, an argument beside the query -- is REFUSED with a structured error naming the offending JSON Pointer. It is never evaluated-and-ignored: reporting that a fact was weighed when it was not is a fail-open, and every audit of such a decision would inherit the claim.

A refusal is a different shape from a decision (AuthZENError, no decision member), because a request that was never evaluated must not be indistinguishable from one that was evaluated and denied.

Profile negotiation. AuthZEN 1.0's response is a bare boolean. What AxonFlow adds -- the four-valued state, obligations, the safe reason code -- rides in context and is returned ONLY to a caller that sent the X-Axonflow-AuthZEN-Profile header naming a profile version this build emits. A caller that did not negotiate receives the boolean alone; a caller that named a version this build does not emit is refused with 406 rather than answered with the boolean, because a silent fallback would report that the negotiation succeeded.

What the context does NOT carry, stated so you do not wait for it. There is no approval challenge on this surface. The route is an adapter over POST /api/v1/decide, and that response names no eligible approver set, no quorum and no challenge expiry -- so there is no requirement to render, and synthesising one would hand your enforcement point a fabricated approval policy to enforce. A decision awaiting approval arrives as state: CHALLENGE with decision: false; act on it by holding, and obtain the challenge itself from the human-approval surfaces. Earlier revisions of this document and of the authzen_evaluation capability entry promised the challenge here, and no response ever carried one.

The one case where not negotiating changes the ANSWER, not just the shape. An evaluation that would otherwise be ALLOW but carries a mandatory obligation is answered {"decision": false} to a caller that did not negotiate the profile. The obligation is a precondition of the permission, not a decoration on it, and it rides in the context such a caller does not receive -- so returning true would hand out a permission whose condition the enforcement point never sees and cannot discharge. ADR-065 invariant 8 prescribes deny for a mandatory obligation an enforcement point cannot enforce, and one that cannot receive it is the limiting case. Everything else is unchanged for a bare AuthZEN 1.0 caller: an allow carrying no mandatory obligation is still true, and the denied, challenged and errored paths are untouched. Negotiate the profile if you can discharge obligations -- a caller that sends the header gets the true and the obligation together. Operationally the denial is counted under outcome="obligation_withheld" on axonflow_authzen_requests_total, logged, and audited as blocked with policy_details.authzen_obligation_withheld, so an operator can find the integrations that need the header.

Available at all tiers -- the evaluation behind it is the same one Decision Mode uses.

header Parameters
X-Axonflow-Client
string
Example: mcp-proxy/0.3.1

Optional client-version telemetry header (<client>/<version>, e.g. mcp-proxy/0.3.1 or claude-code/1.9.1). Enterprise deployments with the client_version_telemetry capability count validated values in the axonflow_client_version_requests_total metric on the decide and MCP check-output planes. Telemetry only — never used for authentication or authorization; invalid values are ignored.

X-Axonflow-PEP-Handshake
string <= 4096 characters

The ADR-065 PEP capability handshake: base64url of a compact JSON document in which an external enforcement point declares what it is and which obligations it can discharge. See PEPHandshake for the document.

Absent is the default and changes nothing. A caller that omits the header takes byte-for-byte the path it took before this header existed.

A header that is PRESENT and cannot be read is refused, never treated as absent: degrading a malformed declaration to "legacy caller" would go on handing an enforcement point obligations it had just said it cannot discharge. The refusal is 400 and its message names this header, which matters on /api/v1/access/evaluation where the refusal is rendered through that surface's existing incomplete_evaluation code and the message is the only thing distinguishing a malformed HEADER from a malformed body ENVELOPE.

Present more than once is refused: RFC 7230 permits an intermediary to join repeated field lines with a comma, and a comma is outside the base64 alphabet, so a joined pair can only decode to malformed. That is why the document is base64 rather than raw JSON, which would join into something a lenient parser might accept.

When a decision carries a mandatory obligation the declared set does not cover, the request is answered 200 with verdict: deny and a reason beginning pep_capability_unsupported (ADR-065 invariant 8) - a decision about the request, not a transport error. Enterprise deployments only; a Community deployment records the declaration and emits the obligation as it does today.

X-Axonflow-AuthZEN-Profile
string
Example: axonflow-authzen-profile-2026-08-29

The AxonFlow AuthZEN profile the caller can interpret. Send axonflow-authzen-profile-2026-08-29 to receive the context payload. Absent or empty, the caller asked for AuthZEN 1.0 and the response carries the boolean decision only -- EXCEPT that an otherwise-allowed decision carrying a mandatory obligation is answered {"decision": false}, because that obligation rides in the context this caller does not receive and it must not be given a permission whose precondition it will never see. Naming a version this build does not emit is REFUSED with 406, because answering it with the bare boolean would report that the negotiation succeeded and an enforcement point would proceed on an allow whose mandatory obligation it never saw.

traceparent
string

W3C trace-context header. When present and valid the trace-id is reused so multi-layer decisions correlate.

Request Body schema: application/json
required
One of
required
object

The singular member. It has no shared base to inherit from, so it must carry its own subject, action and resource.

object (AuthZENBulk)

The plural envelope. The decision count is fixed by the mapping, never by argument data, so an empty evaluations array is malformed rather than a request for zero decisions.

Responses

Request samples

Content type
application/json
Example
{
  • "evaluation": {
    }
}

Response samples

Content type
application/json
Example
{
  • "decision": true,
  • "context": {
    }
}