All articles

API reference

sympy.ai serves its verified math agent over HTTP at https://api.sympy.ai. There are two endpoints, both authenticated with the same API key:

EndpointShapeUse it when
POST /v1/solvenative RESTyou want the verification metadata — verified, the notes, the node trail
POST /v1/messagesAnthropic Messages APIyou already have Anthropic SDK code and want to point it here

Authentication

Create an API key on your account page or dashboard — it is shown once, and starts with mv_. Both endpoints accept either header:

X-API-Key: mv_xxxxxxxx... # or Authorization: Bearer mv_xxxxxxxx...

Usage is billed against your plan's token balance and recorded with source=api. See Account & settings for key management.

POST /v1/solve

bash
curl https://api.sympy.ai/v1/solve \
  -H "X-API-Key: $SYMPY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"problem": "integrate x^2", "model_tier": "flash"}'
FieldTypeNotes
problemstringrequired — the question, in plain language
model_tierstring"flash" (default) or "pro"
conversation_idstringoptional — reuse to continue a thread

The response carries the agent's verification record, which is the reason to prefer this endpoint over the Anthropic-compatible one:

json
{
  "answer": "The integral equals x^3/3 + C.",
  "verified": true,
  "verification_notes": "…",
  "usage": { "prompt_tokens": 812, "completion_tokens": 143, "total_tokens": 955 },
  "conversation_id": "…",
  "verification_strategy": "sympy",
  "nodes_visited": [{ "node": "plan", "duration_ms": 412 }]
}

verification_strategy is the lane the verifier chose (sympy, sage, or both), and nodes_visited is the ordered per-node trail with timings and token deltas.

POST /v1/messages

Request and response match Anthropic's POST /v1/messages, so an Anthropic SDK pointed at https://api.sympy.ai works unchanged.

bash
curl https://api.sympy.ai/v1/messages \
  -H "x-api-key: $SYMPY_API_KEY" \
  -H "content-type: application/json" \
  -d '{
    "model": "sympy-solve",
    "max_tokens": 1024,
    "messages": [
      { "role": "user", "content": "Integrate x^2 from 0 to 1" }
    ]
  }'

Anthropic SDK (Python)

python
from anthropic import Anthropic

client = Anthropic(
    api_key="mv_your_key",
    base_url="https://api.sympy.ai",
)

message = client.messages.create(
    model="sympy-solve",
    max_tokens=1024,
    messages=[{"role": "user", "content": "Integrate x^2 from 0 to 1"}],
)
print(message.content[0].text)

Anthropic SDK (TypeScript)

typescript
import Anthropic from "@anthropic-ai/sdk";

const client = new Anthropic({
  apiKey: "mv_your_key",
  baseURL: "https://api.sympy.ai",
});

const message = await client.messages.create({
  model: "sympy-solve",
  max_tokens: 1024,
  messages: [{ role: "user", content: "Integrate x^2 from 0 to 1" }],
});
console.log(message.content[0].text);

Response

A standard Anthropic message object. The answer is a single text block; usage reports input/output tokens. The verified flag and verification notes are not part of this shape — use /v1/solve if you need them.

json
{
  "id": "msg_…",
  "type": "message",
  "role": "assistant",
  "model": "sympy-solve",
  "content": [{ "type": "text", "text": "The integral equals 1/3." }],
  "stop_reason": "end_turn",
  "stop_sequence": null,
  "usage": { "input_tokens": 812, "output_tokens": 143 }
}

Streaming

Set "stream": true to receive the Anthropic SSE sequence — message_startcontent_block_startcontent_block_deltacontent_block_stopmessage_deltamessage_stop. The Anthropic SDK's streaming helpers consume it unchanged. /v1/solve does not stream.

Models

Any model string is accepted; it only selects a tier. A name containing pro, opus, reasoner, think, reasoning, -r1, or /r1 routes to the higher-effort pipeline — everything else to the fast one.

Errors

The two endpoints use different error shapes, because each matches the convention of the API it imitates.

/v1/messages returns the Anthropic envelope { "type": "error", "error": { "type", "message" } }:

HTTPerror.typeMeaning
401authentication_errorMissing, invalid, or revoked API key
400invalid_request_errorMalformed request
429rate_limit_errorRate limited (with retry-after)
403billing_errorToken balance exhausted
500api_errorAgent or upstream failure

/v1/solve returns { "detail": "…" }:

HTTPMeaning
401Missing, invalid, or revoked API key
429Rate limited (with Retry-After)
402Insufficient token balance
500Agent or upstream failure

Note the mismatch on an exhausted balance: /v1/solve answers 402, while /v1/messages answers 403 to stay within Anthropic's error vocabulary. Handle both if you call both.

Per-key rate limits follow your plan, and are shared across /v1/solve, /v1/messages, and the MCP server — one limit governs all three.

Two HTTP APIs — a native REST endpoint and an Anthropic-compatible Messages API.