AxioRankDocs

Gateway API

The raw HTTP contract behind every AxioRank SDK, callable from any language.

The SDKs are thin wrappers over these endpoints. Use them directly from any language. All requests authenticate with a bearer token and send/receive JSON.

Authorization: Bearer axr_live_...
Content-Type: application/json

The base URL is your deployment, https://app.axiorank.com by default. The canonical versioned base path is /api/v1 (e.g. POST /api/v1/gateway/tool-call); the unversioned /api/... paths shown below remain available as aliases. See Versioning & stability.

Prefer an interactive explorer? Open the API Reference to try requests live, or import the machine-readable OpenAPI spec into Postman / your codegen of choice.

Idempotency

POST /api/gateway/tool-call and POST /api/gateway/verify-card accept an optional Idempotency-Key header. Send a unique key (e.g. a UUID) and a safe retry replays the first response instead of re-executing, so a dropped connection never double-counts quota or writes a duplicate audit row. Keys are scoped to your API key and retained for 24 hours.

  • Reusing a key with a different request body → 422.
  • A retry while the first request is still in flight → 409 (retry shortly).
  • Every response carries Idempotent-Replayed: true|false.

POST /api/gateway/tool-call

Score a tool call and apply your policies.

Request

{ "tool": "aws.delete_bucket", "arguments": { "name": "prod-data" } }

Response

{
  "decision": "allow",
  "reason": "no matching deny policy",
  "risk": 12,
  "auditLogId": "log_...",
  "signals": [],
  "approvalId": null
}
  • decision: allow, deny, or hold.
  • risk: 0–100.
  • signals: redacted content-inspection findings that contributed to the score.
  • approvalId: present only when decision is hold (see below).
  • 401 is returned for a missing/invalid key; 400 for a malformed body.

GET /api/gateway/approvals/{approvalId}

When a require_approval policy fires, the tool-call response is decision: "hold" with an approvalId. Poll this endpoint until a human resolves it; the server long-polls (~8s per request), so polling is cheap.

Response

{ "status": "approved", "decision": "allow", "reason": "approved by ops" }

decision stays hold while pending. The SDKs do this polling for you and only ever surface the final allow / deny.

POST /api/gateway/verify-card

Preflight an external MCP server / A2A agent before trusting it. Send a url to fetch the card from, or an inline document.

{ "url": "https://mcp.acme.com" }

The response carries decision (allow | review | deny), risk, the resolved identity (signature validity, key domain-binding), declared capabilities, auth, and warnings.

POST /api/gateway/verify-request

Verify an inbound agent request against an inbound surface's site key (axr_site_...). One endpoint backs every surface kind. For a website or HTTP surface, send the request metadata (the axioGuard middleware and the SDK verifyRequest / verify_request helpers build this for you):

{
  "method": "GET",
  "authority": "api.acme.com",
  "path": "/agents",
  "signatureInput": "sig1=(...)",
  "signature": "sig1=:...:",
  "signatureAgent": "https://openai.com",
  "headers": { "user-agent": "GPTBot/1.0" }
}

For an agent-native surface (an MCP server, an A2A agent, an HTTP API, or a webhook), send surfaceKind plus the caller's identity material instead. The SDK verifySurface / verify_surface helpers build this:

{
  "surfaceKind": "mcp_server",
  "operation": "tools/call",
  "agentCard": { "...": "the connecting agent's signed card" }
}

The response includes decision (allow | challenge | block), verification (status, method, confidence), risk, and a per-kind challenge instruction for enforcing a non-allow verdict.

POST /api/gateway/token

Exchange a long-lived credential for a short-lived, scoped token, so an agent carries a narrow, expiring credential instead of a static key. Two grants are supported.

Key exchange. Present an agent API key in the Authorization header. The body is optional; omit it for a token that inherits the key's scopes.

{ "scopes": ["gateway:write"], "ttl_seconds": 900 }

Federated (workload identity). Present a platform OIDC token (GitHub Actions, AWS, GCP) as subject_token, with no AxioRank key at all. AxioRank verifies it against the issuer's JWKS and mints a token for the bound agent, so no long-lived AxioRank secret ever lives on the runner.

{ "subject_token": "<platform OIDC token>", "scopes": ["gateway:write"] }

Response. Both grants return the same shape. Use token as the Authorization bearer on subsequent gateway calls until it expires.

{
  "token": "<short-lived token>",
  "token_type": "Bearer",
  "expires_at": "2026-07-07T12:15:00Z",
  "expires_in": 900,
  "scopes": ["gateway:write"]
}

A token can only narrow the credential's scopes, never widen them: a requested scope the key does not carry is dropped, and requesting none that it carries is a 403. The SDKs run this exchange for you when you set useTokens (with optional tokenScopes, tokenTtlSeconds, and a subjectToken for the federated grant), so the static key stays on your control plane instead of in the agent.

Next steps

On this page