Anthropic compatible API

Spark answers POST /v1/messages and POST /v1/messages/count_tokens, so an Anthropic SDK works with base_url = http://<host>:8080 (no /v1) and a Spark key as the API key. The SDKs send the key in x-api-key. A Authorization: Bearer header works as well.

The parameters each route reads are in the compatibility matrix.

Messages

curl http://localhost:8080/v1/messages \
-H "x-api-key: $SPARK_KEY" -H "anthropic-version: 2023-06-01" -H "Content-Type: application/json" \
-d '{
"model": "smollm2-135m-instruct-q8_0",
"max_tokens": 256,
"messages": [{"role": "user", "content": "Hello!"}]
}'

max_tokens is required, as it is on Anthropic's API. A request without it fails with 400 and the message max_tokens: Field required.

Streaming

stream: true returns Anthropic's typed events: message_start, content_block_start, content_block_delta, content_block_stop, message_delta and message_stop. Thinking comes as a thinking block before the text. A tool call comes as a tool_use block.

Content blocks

Block Support
text Yes.
image with a base64 or url source Yes, for a model with a vision projector. The Files API is not supported.
thinking in earlier assistant turns Read back as the turn's reasoning. redacted_thinking is ignored.
tool_use and tool_result Yes. is_error: true prefixes the result with Error:.
document Refused with 400.

Server tools such as web search and code execution have a type and no schema. Spark skips them, because it cannot run them. tool_choice is read only for {"type": "none"}, which turns tools off.

Thinking is on when thinking.type is enabled or adaptive. The response then carries a thinking block, with an empty signature.

Prompt caching

cache_control on a content block, on the system prompt or on the tools marks a breakpoint. Spark writes the shared prefix as a KV snapshot while it prefills, and reuses it on the next request that starts the same way. A top-level cache_control marks everything up to the last message.

usage reports input_tokens, cache_read_input_tokens, cache_creation_input_tokens and output_tokens. See KV cache and snapshots.

Counting tokens

POST /v1/messages/count_tokens takes the same body as /v1/messages and returns {"input_tokens": n}. It tokenizes with the model's own tokenizer and chat template, so the count includes the template's tokens. It needs the model to be available, but does not generate.

Sampling parameters

temperature, top_p, top_k and stop_sequences are read, together with max_tokens. stop_reason is end_turn, max_tokens, stop_sequence or tool_use.

Errors

Errors use Anthropic's shape:

{"type": "error", "error": {"type": "invalid_request_error", "message": "max_tokens: Field required"}}

A missing or wrong key gives 401 with authentication_error. An unknown model gives 404 with not_found_error.