BuildToken counting

Token counting

⚠️
Preview — this feature is being built; the design below is the spec.

Find out how many input tokens a request would use before you send it. The count uses the model’s real tokenizer and includes everything that is billed as input: the Syntic identity instruction, your system message, every message, tool definitions, images and documents. The model is not run, and counting is free.

When to use it

  • Check that a long conversation or document still fits the context window.
  • Estimate cost before a large job or batch.
  • Decide when to trim or summarise history, or turn on context management.
  • Show users how much room is left in a chat.

Endpoint

POST https://app.syntic.ai/v1/chat/completions/count_tokens
Authorization: Bearer sk_live_...
Content-Type: application/json

A matching POST /v1/messages/count_tokens takes the Messages body.

Request body

The same body you would send to /v1/chat/completions. These fields affect the count:

FieldCounted
modelRequired. Tokenizers differ between models.
messagesYes, including text, images, files and tool calls/results.
toolsYes, as they would be presented to the model.
response_formatYes, the schema adds input tokens.
reasoning, mcp_serversYes, for any instructions they add.

Fields that only affect output (max_tokens, stream, temperature, stop) are accepted and ignored, so you can pass your real request unchanged.

Response

{
  "object": "token_count",
  "model": "Amara S1.2",
  "input_tokens": 18342,
  "details": {
    "system_tokens": 412,
    "message_tokens": 15210,
    "tool_tokens": 1890,
    "image_tokens": 765,
    "document_tokens": 0
  },
  "context_window": 262144,
  "remaining_tokens": 243802
}
FieldDescription
input_tokensThe total that usage.prompt_tokens would report.
detailsBreakdown by source. Parts add up to input_tokens.
context_windowThe model’s context size.
remaining_tokenscontext_window minus input_tokens. Your reply (max_tokens) must fit here.

The count matches the real request exactly, except that server-side tool results (for example web search results added during the request) cannot be known in advance.

Examples

curl https://app.syntic.ai/v1/chat/completions/count_tokens \
  -H "Authorization: Bearer $SYNTIC_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "Amara S1.2",
    "messages": [
      { "role": "system", "content": "You are a careful contracts assistant." },
      { "role": "user", "content": "Summarise clause 14 of the attached lease." }
    ]
  }'

Errors

Unified envelope. Validation is the same as the real endpoint, so a request that counts without error will also pass validation when sent.

StatuscodeCause
400messages_requiredNo messages.
400model_requiredmodel missing. Unlike chat completions, counting has no default model.
400any validation codeSame checks as the real request (images, files, schemas, tools).
404model_not_foundUnknown model.
429rate_limitedOver the counting limit.

Limits and cost

PriceFree. Not billed and does not use plan allowance.
Rate limitSeparate from inference: 100 requests per minute per key.
Request sizeSame as the real endpoint.

Remote image URLs are fetched to measure them, which can make counting slower than you expect; send sizes you already know or use Files.

Build notes for the platform team

  • Must use the real tokenizer or the model service’s own count endpoint. The current internal estimate of about 4 characters per token is not acceptable here.
  • Share the validation and request-building code with the real endpoint so the two can never disagree.
  • Include the identity instruction in the count.
Was this page helpful?