The agent, as an API.
One simple API. Send your chat, get an answer back. We make the chat smaller before it reaches the AI, so your bill stays low even as the conversation grows, and nothing important is lost. Use your own AI key and pay in plain dollars.
https://axiomsymbiotic.org
Authorization: Bearer ak_...
Prepaid USD · per call
Two keys, one call.
Every request carries two keys. Your Axiom key is your account and tracks the call. Your AI key is your own Anthropic or OpenAI key. We use it for that one call and never save it.
| Header | Required | Value |
|---|---|---|
Authorization |
yes | Your Axiom key as Bearer ak_... (fallback header: X-Api-Key) |
X-Provider-Key |
yes | Your AI key. May instead be sent as provider_key in the body; the header wins. |
Content-Type |
yes | application/json |
Don't have an Axiom key yet? Request access. Keys come with a balance you've paid into.
POST /v1/agent
Send the full chat each turn. The response is the AI's reply plus your usage and the dollar cost of the call. The AI still sees everything it needs, so the answer is just as good.
Request body
| Field | Type | Default | Notes |
|---|---|---|---|
model | string | required | AI model id, e.g. claude-sonnet-4-6. |
messages | array | required | Non-empty. Each item { "role": "user" | "assistant", "content": "..." }. |
provider | string | "anthropic" | "anthropic" or "openai". |
max_tokens | int | 8192 | Output cap. |
base_url | string | — | Override for OpenAI-compatible endpoints. |
reduce | bool | true | Set false to send the chat as-is. |
provider_key | string | — | Your AI key if not sent on the header. |
Example request
curl https://axiomsymbiotic.org/v1/agent \
-H "Authorization: Bearer ak_your_key" \
-H "X-Provider-Key: your_ai_key" \
-H "Content-Type: application/json" \
-d '{
"model": "claude-sonnet-4-6",
"provider": "anthropic",
"messages": [
{ "role": "user", "content": "Summarize the chat so far." }
]
}'
Example response
{
"ok": true,
"id": "ax_9f2c4b1e...",
"model": "claude-sonnet-4-6",
"message": {
"role": "assistant",
"content": "..."
},
"stop_reason": "end_turn",
"truncated": false,
"duration_ms": 1840,
"usage": {
"output_tokens": 96
},
"billing": {
"uncached_usd": 0.001476,
"charged_usd": 0.001107,
"balance_remaining": 24.9989
}
}
billing.uncached_usd is the normal price; billing.charged_usd
is what you paid; billing.balance_remaining is your balance after.
GET /v1/account
Check your balance and lifetime usage. No body required.
Example response
{
"ok": true,
"tenant": "your-tenant",
"balance_usd": 24.9989,
"lifetime": {
"calls": 312,
"uncached_usd": 7.5012,
"charged_usd": 5.0025
}
}
Error format.
Every error is JSON: { "ok": false, "code": "...", "error": "..." }.
code is a stable machine string; error is human-readable.
| Status | code | Meaning |
|---|---|---|
400 | bad_request | Missing or unreadable body, or a missing model / messages. |
400 | missing_provider_key | No AI key on the header or in the body. |
401 | unauthorized | Missing, invalid, expired, or inactive Axiom key. |
402 | payment_required | Balance used up. Add funds to continue. |
502 | provider_error | The AI rejected the call (bad AI key, bad model, or rate limit). |
504 | provider_timeout | The AI took too long. Try a smaller turn or a faster model. |
Prepaid, in dollars.
Each key has a balance you've paid into. A call subtracts charged_usd from
it, and only runs while the balance is above zero. You bring your own AI key and pay
that company directly. We only charge for our part, in plain dollars.
We make your chat smaller without losing anything that matters. The same chat gives the same result every time, and the AI still gets everything it needs to answer.