---
title: "Process client request"
method: POST
path: "/api/request"
tags: ["Proxy Mode"]
---

# Process client request

`POST /api/request`

## Request

- Base URL: `https://agent.getaxonflow.com`
- URL: `https://agent.getaxonflow.com/api/request`
- Auth: none declared. Required headers: `Authorization`
- TypeScript: <https://skmtc.dev/getaxonflow/apis/axonflow-agent-api/docs/api/request/post.ts> (a function with typed inputs; its response is checked against the schema)

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.**

## Headers

- `Authorization` string, required
- `X-Client-Secret` string

## Request body

- ClientRequest
  - `query` string, required: The query or prompt to process
  - `user_token` string: JWT token for user authentication
  - `client_id` string, required: Registered client application ID
  - `request_type` '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: Skip LLM calls (for testing)
  - `context` object: Additional context for request processing
  - `media` object[]: 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.

## Response `200`

Request processed successfully

- ClientResponse
  - `success` boolean
  - `data` unknown
  - `result` string: Result string for multi-agent planning
  - `plan_id` string: Plan ID for multi-agent planning
  - `metadata` object: Execution metadata for multi-agent planning
  - `error` string: Error message if success is false
  - `code` 'ERR_TIER_LIMIT_HUMAN_PRINCIPAL' | 'ERR_TIER_LIMIT_SERVICE_PRINCIPAL' | 'ERR_TIER_LIMIT_ORG_ROOT_POLICY' | 'ERR_TIER_LIMIT_NODE': The refusal's machine-readable code, present on a licence-ceiling (tier-limit) refusal: one code per admission dimension. On `/api/request` only the two principal codes occur. Omitted on every other response.
  - `blocked` boolean: True if the request was blocked, by policy, a cost budget or the licence's ceiling
  - `block_reason` string: Reason for blocking
  - `policy_info` PolicyEvaluationInfo
    - `matched_policies` string[]: The policies that matched the request, the deciding one first. `policies_evaluated` carries the same list under its older name.
    - `policies_evaluated` string[]: The same list as `matched_policies`, kept under its older name for existing consumers.
    - `static_checks` string[]: List of static checks performed
    - `processing_time` string: Time taken for policy evaluation
    - `tenant_id` string: Tenant ID for the request
    - `code_artifact` object: Code-artifact metadata captured by the code-governance evaluation path when the request carried code content (LLM-generated or user-provided). Mirrors the SDK's `CodeArtifact` type — language, code_type, size_bytes, line_count, secrets_detected, unsafe_patterns, policies_checked.
  - `budget_info` object: Budget enforcement status (Issue #1082) — present when a budget check ran. Surfaces current usage vs limits so callers can render budget-aware UI without a separate /api/v1/budgets call.
  - `media_analysis` object: Media-governance analysis result — populated when the request carried a `media` payload. Shape mirrors `MediaAnalysisResponse`.
  - `engine` 'anchored': Which policy engine authored this verdict: `anchored`, the ADR-065 decision plane, which authors every verdict on this route (PRD v11 §1.1). Since v11.0.0 (#4253) `legacy` is never written: the tier engine that authored it after an anchored approval is retired. Omitted on a refusal no engine decided.
  - `subject_type` string: The type of principal the verdict was decided for (PRD v11 §1.6): `User` for a verified user token, `Client` when the request presented no user identity and its client credential is the principal. Omitted wherever `engine` is.
  - `policy_bundle` string: The digest of the policy set that decided: the system corpus's restriction for this route and the organization root - the organization's active typed document composed with the deployment's baseline permission pack, or, while it has published nothing, the implicit bundle of that pack and the organization template. A rollback reinstates an earlier digest. Omitted wherever `engine` is.
  - `policy_packs` string[]: The add-on policy packs (PRD v11 §1.9) whose controls composed into `policy_bundle` on this route, each as `<pack id>@<digest of the pack document the deployment instantiated>`, sorted. Omitted when the deployment installs no pack or none binds on this route.
  - `legacy_validators` object[]: A checksum validator that acted BEFORE the anchored engine decided (#4122): under an organization's recorded `pii=block` or `pii=redact` detection override, the Indonesia or India validator blocked the request or masked the response ahead of the decision plane. Present on this envelope only for an MCP connector route's response-pass refusal, and never on `/api/request`, whose request pass runs no checksum validator. Omitted when none did, which is every request without such an override.
    - `validator` 'indonesia_pii' | 'india_pii', required
    - `action` 'blocked' | 'masked', required
  - `response_plane` object: The orchestrator response plane's decision on the LLM response `/api/request` forwarded (PRD v11 §1.1). It is a SEPARATE decision from the top-level `engine`, `subject_type` and `policy_bundle`, which name the request pass that let the request through: the response is decided afterwards, on the orchestrator, for the client credential the agent forwarded. Omitted on a response no response-plane decision covers, including every refusal of the request itself.
    - `engine` 'anchored'
    - `subject_type` string: The principal type the response was decided for: `Client` on every edition.
    - `policy_bundle` string: The digest of the policy set that decided the response.
    - `verdict` 'allowed' | 'redacted' | 'blocked': `allowed` (the response as the provider sent it), `redacted` (`data` carries it masked) or `blocked` (withheld: `success` is false, `blocked` is true, and the refusal is not counted against the client's circuit breaker, because the caller did not cause it).

## Other responses

- `400`: Invalid request body or parameters
- `401`: Missing or invalid authentication. Handler-written 401s use the `{success, error}` envelope; 401s written by the auth middleware use the `{"error": {"code", "message"}}` envelope (JSONError).
- `402`: A configured cost budget blocks the request (Enterprise cost controls; `blocked: true`, `policy_info.matched_policies` `["budget_exceeded"]`), or the licence's ceiling refuses a principal: the client credential's service principal at authentication, or the verified user token's human principal when the user is resolved. Both tier-limit refusals answer one shape: `blocked: true`, `code` the `ERR_TIER_LIMIT_*` code of the refused dimension, and `error` and `block_reason` the refusal's message, which begins with that code. A tier-limit refusal carries `Retry-After` only when the licence ledger could not be reached (its message says the ledger cannot be reached); a refusal over the ceiling has no reset and carries none. Both bodies are a `ClientResponse`. This route answers no 429 for the ceiling.
- `403`: Request refused by the anchored engine. `block_reason` is the refusal's reason code (for example `explicit_constraint`) and `policy_info.matched_policies` names the policy that decided it, first. Since v11.0.0 no refusal on this route comes from another engine, and none is an approval hold (#4253).
- `500`: Internal server error
- `503`: The anchored engine could not decide the request (for example, no enforcer is wired in the process). The route fails CLOSED and never falls back to another engine: `blocked` is true and `policy_info.matched_policies` is `["decision_enforcement_unavailable"]`.

---

[API](https://skmtc.dev/getaxonflow/apis/axonflow-agent-api.md) - [All operations](https://skmtc.dev/getaxonflow/apis/axonflow-agent-api/llms.txt) - [OpenAPI document](https://skmtc.dev/getaxonflow/apis/axonflow-agent-api/revisions/34d30fcb7fa1?raw)
