BETA

Docs
Documentation

Create a message

POST/v1/messages

Native Anthropic Messages API — for Anthropic-protocol clients (Claude Code and other Anthropic SDKs) that connect via ANTHROPIC_BASE_URL/ANTHROPIC_API_KEY instead of an OpenAI-compatible provider block.

Request body

model
required, string — a catalog id from GET /v1/models
max_tokens
required, number — the Anthropic API requires it, unlike OpenAI's chat/completions
messages
required, array — role: "user"/"assistant", content as a string or content blocks (text, tool_use, tool_result)
system
optional, string or array of text blocks
tools
optional, array — Anthropic tool-definition shape (name, description, input_schema)
tool_choice
optional — auto / any / none / a named tool
stop_sequences
optional, array of strings
stream
optional, boolean — Anthropic-style SSE events when true
temperature / top_p
optional, forwarded unmodified

cURL example

terminal
curl https://apily.pro/v1/messages \
  -H "x-api-key: apily_your-api-key" \
  -H "Content-Type: application/json" \
  -d '{"model":"claude-opus-5","max_tokens":1024,"messages":[{"role":"user","content":"ping"}]}'

Response

An Anthropic Message object — content (an array of text/tool_use blocks), stop_reason, and usage (input_tokens/output_tokens) with the real token counts for the request, not an upfront estimate. Streaming requests get the standard Anthropic SSE sequence — message_start → content_block_start/delta/stop → message_delta → message_stop.

Not supported

  • image content blocks, and any unrecognized content-block type, return a 400 invalid_request_error instead of being silently dropped.
  • The thinking request field and thinking/redacted_thinking history blocks are silently ignored — most Anthropic clients send thinking by default, so this keeps the endpoint usable rather than rejecting every request.
  • cache_control (prompt caching) is not proxied to the upstream model.
  • The Anthropic Batches and Token Counting APIs (/v1/messages/batches, /v1/messages/count_tokens) are not implemented.

Error responses

Errors use the Anthropic error envelope ({ type: "error", error: { type, message } }), not the { error: string } shape used by the OpenAI-compatible routes.

SymptomCauseFix
401 Missing API keyNo auth header was sent.Apily accepts Authorization: Bearer … and x-api-key: ….
401 Invalid API keyKey copied with stray spaces, truncated, or revoked.Copy the key whole from the API page in your Apily account, the apily_ prefix included.
403 Email not verifiedYour Apily account's email address isn't verified yet.Verify your email from the banner in the Apily app, then retry.
404 Model not foundThe model ID isn't in the Apily catalog.Copy the exact ID from GET /v1/models or the Models page in your account.
503 Model temporarily unavailableThe model exists, but no upstream provider is reachable right now.Retry in a moment — it usually recovers within a minute. Switch models if it keeps happening.
402 Insufficient balanceYour token balance can't cover the request's estimated cost.Top up your balance on the Billing page in your Apily account.
429 Too many requestsYour account sent more than 600 /v1/* requests in a minute — all of your API keys share one budget. The body is { error: { message, type: "rate_limit_error", code: "rate_limit_exceeded" }, retryAfterSeconds }.Wait the Retry-After header (or retryAfterSeconds) before retrying, and lower request concurrency.
502 Upstream errorThe upstream provider returned an unexpected error.Retry the request; try a different model if it persists.