API reference

POST /v1/messages — single-turn requests

Reference for the SubToAPI messages endpoint: request fields, model aliases, JSON mode, thinking budget and the normalized response with token usage.

Updated

One request in, one normalized answer out. Use this endpoint for classification, extraction, summaries, rewrites and any task that fits a single prompt.

terminal
curl -X POST \
  "https://api.subtoapi.app/v1/messages" \
  -H "Authorization: Bearer $SUBTOAPI_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "system": "You are a helpful assistant.",
    "messages": [
      { "role": "user", "content": "Hello" }
    ],
    "model": "balanced"
  }'

Request body

Fields
messagesrequired
Message[]
User/assistant turns. Each content is a string or an array of content blocks. Max 200 messages.
system
string
System instructions. Max 500,000 characters.
model
"fast" | "balanced" | "best"
Public model alias. Defaults to balanced.
json_mode
boolean
Ask for JSON-friendly output where the model supports it.
thinking_budget
number
Optional extended-thinking budget (tokens) where the selected tier supports it.
temperature
number
Optional sampling temperature (0–1) where supported.

Response

Fields
id
string
Provider message id.
request_id
string
SubToAPI request id (req_…) — also sent as the x-request-id header. Quote it in support requests.
content
ContentBlock[]
Normalized text and tool_use blocks in order.
usage
object
input_tokens, output_tokens, cache_read_tokens, cache_write_tokens, total_tokens.
latency_ms
number
Server-side provider latency for this request.
model · provider
string
Resolved public alias and "claude".
stop_reason
string | null
"end_turn", "max_tokens", "tool_use" or null.
200 OK
{
  "id": "msg_...",
  "provider": "claude",
  "model": "balanced",
  "content": [
    { "type": "text", "text": "Hello! How can I help you today?" }
  ],
  "usage": {
    "input_tokens": 2510,
    "output_tokens": 74,
    "cache_read_tokens": 2048,
    "cache_write_tokens": 0,
    "total_tokens": 2584
  },
  "latency_ms": 842,
  "request_id": "req_..."
}

JSON mode

Set json_mode: true and describe the shape you want in the system prompt. The model is steered towards valid JSON; always parse defensively and retry on a parse error.

request.json
{
  "system": "Reply with JSON only: { \"sentiment\": \"positive\" | \"neutral\" | \"negative\", \"confidence\": number }",
  "messages": [{ "role": "user", "content": "The onboarding was smooth and support answered in minutes." }],
  "model": "fast",
  "json_mode": true
}

Extended thinking

For hard problems pass thinking_budget (tokens). The best and balanced tiers support it; fast ignores it. Larger budgets cost latency, so start around 2,000–4,000 and measure.

Limits

Text fields

500k chars

system / content · 500,000 chars each

Conversation messages

200

turns per /v1/conversation call

Tools

50

tool definitions per request

Request body

4 MB

/v1/* · 4,000,000 bytes

Frequently asked questions

Can I stream the response?
Yes — add "stream": true to the body and the endpoint answers with the same server-sent events as /v1/conversation/stream.
Where do token counts come from?
They are reported by the provider for this exact request and stored as usage metadata, so the dashboard and your logs agree.