Models and Token Counting
Purpose and Scope
Model selection and token counting are planning steps that happen before or alongside a Messages API call. A model identifier tells Claude which model family and version should process the request, while token counting estimates how large the structured message input is before you create the actual message. In this SDK, those concerns meet at the Messages resource: the same conversational shape used for generation is also the shape used for token-count estimation, and batch requests preserve the same model, messages, and max_tokens fields inside each queued request.
Sources: src/resources/messages/index.ts, src/resources/beta/messages/messages.ts
The official API documentation describes two complementary operations: retrieving model metadata with GET /v1/models/{model_id} and counting message tokens with POST /v1/messages/count_tokens. The repository evidence for this page shows the TypeScript SDK side of that workflow through generated Messages exports, beta Messages exports, and batch request examples that include a concrete model value. Use model retrieval when you need metadata or alias resolution, and use message token counting when you need to budget a specific prompt before sending it for generation.
Sources: src/resources/messages/index.ts, src/resources/beta/messages/index.ts, src/resources/beta/messages/batches.ts
Relevant Source Files
src/resources/beta/messages/index.ts- Re-exports the beta Messages and Batches resource classes plus beta message, content, context-management, and token-count-related types used by beta workflows.src/resources/messages/index.ts- Re-exports the stable Messages and Batches resource classes plus public stable types such asMessage,MessageParam,MessageTokensCount,MessageCountTokensTool, andModel.src/internal/detect-platform.ts- Builds the SDK runtime metadata headers, including package version, operating system, architecture, runtime, and runtime version, which accompany API calls independently of the selected model.src/resources/beta/messages.ts- Provides the beta messages namespace barrel by exporting./messages/index, makingclient.beta.messagesresources available through the generated SDK tree.src/resources/beta/messages/batches.ts- Implements beta message batch methods and demonstrates per-requestmodel,messages, andmax_tokensfields inside batch creation.src/resources/beta/messages/messages.ts- Contains the generated beta Messages resource implementation, including beta message creation and token-counting behavior for beta-enabled message inputs.
Core Concepts
A model identifier is the value passed in a request to choose the Claude model that will process the prompt. The batch implementation’s example uses model: 'claude-opus-4-6' inside the request parameters, alongside messages and max_tokens, which is the same conceptual placement used for ordinary message creation. The stable Messages index also re-exports a Model type, making model selection part of the public typed surface exposed from src/resources/messages/index.ts rather than an untyped string hidden in user code.
Sources: src/resources/messages/index.ts, src/resources/beta/messages/batches.ts
Token counting is not a separate prompt format. The official docs state that the count endpoint accepts the same structured list of inputs used for message creation, including system prompts, tools, images, and documents. The SDK mirrors that relationship by placing token-count-related types next to message types. The stable index re-exports MessageParam, MessageTokensCount, and MessageCountTokensTool, while the beta index includes beta content, tool, context-management, and count-token context-management response types. That layout is a useful signal: build the message once, count it, then send or adjust it.
Sources: src/resources/messages/index.ts, src/resources/beta/messages/index.ts
The count returned by the API should be treated as an estimate for planning, not as a billing record. The product documentation notes that system optimizations can add tokens and that billing reflects user content rather than system-added tokens. In application code, this means token counting is best used for routing, trimming, preflight validation, and cost-aware UX. The SDK types help keep that preflight request close to the eventual message request, reducing the chance that you count one payload shape but send another.
Sources: src/resources/messages/index.ts, src/resources/beta/messages/messages.ts
System-to-Code Mapping
The stable resource namespace is centered on src/resources/messages/index.ts. That file is a generated barrel that exports Messages, Batches, and a large set of message-related public types. For this page, the important exports are the ones that connect model-aware message creation to token planning: MessageParam for conversation turns, Message for generated responses, MessageTokensCount for count results, MessageCountTokensTool for tools that participate in token counting, and Model for model values accepted by message requests.
Sources: src/resources/messages/index.ts
The beta namespace has an extra layer. src/resources/beta/messages.ts exports ./messages/index, and src/resources/beta/messages/index.ts then re-exports beta Messages, beta Batches, and many beta-only message types. This matters because token counting can be affected by beta features such as context management, newer tool types, or beta content blocks. When you use client.beta.messages, keep beta-only request fields and beta headers aligned with the feature you are counting or sending.
Sources: src/resources/beta/messages.ts, src/resources/beta/messages/index.ts, src/resources/beta/messages/messages.ts
Batch processing shows how model selection is repeated across many message requests. In src/resources/beta/messages/batches.ts, Batches.create posts to /v1/messages/batches?beta=true, moves beta fields out of the body, and builds an anthropic-beta header that includes message-batches-2024-09-24. Its example request wraps each message creation request under requests[].params, including model, messages, and max_tokens. That structure lets an application count or validate each request before placing it in a long-running batch.
Sources: src/resources/beta/messages/batches.ts
Runtime detection is intentionally separate from model and token logic. src/internal/detect-platform.ts detects Deno, Edge Runtime, Node.js, browser user agents, or unknown runtimes, then constructs X-Stainless-* metadata such as X-Stainless-Lang, X-Stainless-Package-Version, X-Stainless-OS, X-Stainless-Arch, X-Stainless-Runtime, and X-Stainless-Runtime-Version. These headers describe the SDK environment; they do not select the Claude model or alter the message token budget. That separation keeps operational telemetry distinct from request semantics.
Sources: src/internal/detect-platform.ts
Execution Flow
A typical workflow starts by choosing a candidate model for the user task. If your application needs metadata or alias resolution, call the Models API described in the official API docs before composing the request. Then construct the Messages payload with the same fields you would use for generation: model, messages, optional system content, tools, documents, images, and any relevant beta fields. Counting should happen after the payload is representative, because changing tools or attachments can change the estimate.
Sources: src/resources/messages/index.ts, src/resources/beta/messages/messages.ts
After counting, compare the returned input-token total with your product constraints. You might trim conversation history, compress retrieved context, choose a model with a larger context window, or reject the request with an actionable validation message. Because the SDK exposes both stable and beta message surfaces, keep the count call in the same namespace as the eventual send when beta-only features are present. For example, beta context-management request fields should be counted through the beta Messages surface rather than a stable-only approximation.
Sources: src/resources/beta/messages/index.ts, src/resources/beta/messages/messages.ts
For asynchronous workloads, apply the same discipline before calling the beta batch API. Each batch entry contains its own message creation parameters, so token planning should be performed per request, not once for the whole file or queue. Batches.create begins processing immediately and the generated documentation notes that batches can take up to 24 hours to complete. Preflight counting is therefore especially useful before batch submission, because a bad prompt shape can otherwise enter a long-running workflow.
Sources: src/resources/beta/messages/batches.ts
API Components Reference
| Component | Where it appears | Use in model and token workflows |
|---|---|---|
Messages | src/resources/messages/index.ts | Stable message resource namespace for creating messages and using stable message-related types. |
MessageParam | src/resources/messages/index.ts | Typed representation of user and assistant conversation turns used by message creation and token counting. |
MessageTokensCount | src/resources/messages/index.ts | Public stable type for the token-count response shape. |
MessageCountTokensTool | src/resources/messages/index.ts | Public stable type for tools included in a token-countable message payload. |
Model | src/resources/messages/index.ts | Public stable model type exported with message types, used when selecting a model for a request. |
BetaCountTokensContextManagementResponse | src/resources/beta/messages/index.ts | Beta response type related to counting with context-management behavior. |
Batches.create(params, options?) | src/resources/beta/messages/batches.ts | Submits many model-specific message creation requests and injects the message-batches beta header. |
getPlatformProperties() | src/internal/detect-platform.ts | Produces runtime metadata headers; useful operational context but not part of token budgeting. |
A minimal preflight pattern is to construct the request parameters once, count the tokens, then reuse the same shape for generation if the count is acceptable. The exact method names are generated on the Messages resource, but the public contract is visible in the exported stable and beta types: a request is built from message parameters, a model identifier, and any extra content or tool structures. Keeping those pieces together prevents drift between the counted input and the input actually sent to Claude.
Sources: src/resources/messages/index.ts, src/resources/beta/messages/messages.ts
import Anthropic from '@anthropic-ai/sdk';
const client = new Anthropic();
const params = {
model: 'claude-opus-4-6',
max_tokens: 1024,
messages: [{ role: 'user' as const, content: 'Explain token counting in one paragraph.' }],
};
// Count first, then send if the estimate fits your limits.
const count = await client.messages.countTokens(params);
console.log(count);
const message = await client.messages.create(params);
console.log(message.content);Implementation Details and Caveats
The generated files deliberately separate barrels from implementations. Index files re-export resource classes and types so application imports remain stable, while implementation files such as src/resources/beta/messages/batches.ts contain the HTTP path, request body handling, header construction, pagination type, and result decoding details. This is why most application code should depend on the top-level SDK client and public exported types instead of reaching into generated implementation modules. The implementation details are still useful for understanding how beta headers and request bodies are assembled.
Sources: src/resources/beta/messages/index.ts, src/resources/beta/messages/batches.ts
Beta features require particular attention because headers are part of the API contract. The beta batch implementation removes betas and user_profile_id from the request body and places them in headers, adding the required message-batches-2024-09-24 beta value. The official token-counting docs also mention beta headers for some API capabilities. When token-counting a beta payload, ensure the same beta feature set is active when you later create the message or submit the batch, otherwise the counted shape may not match the executed shape.
Sources: src/resources/beta/messages/batches.ts, src/resources/beta/messages/messages.ts
Model choice can change the meaning of a token estimate. The official docs note that newer model families may tokenize the same input differently, so counts should be measured against the model you plan to use rather than reused across models. In SDK code, this means model routing should happen before the count call when possible. If you count against one model and later route to another, treat the first count as an approximation and consider recounting for high-stakes limits.
Sources: src/resources/messages/index.ts, src/resources/beta/messages/batches.ts
Next Steps
For basic generation, read the Messages API page next and treat token counting as a preflight step before messages.create. For long-running asynchronous work, read Message Batches and apply per-request counting before submission. If your application uses beta context management, beta tools, or Managed Agent features, continue with the beta namespace reference so that headers, request shapes, and response types stay aligned across counting and execution.
Sources: src/resources/messages/index.ts, src/resources/beta/messages/index.ts, src/resources/beta/messages/batches.ts