Repository Public
1# Counting tokens23> For the complete documentation index, see [llms.txt](/llms.txt). Markdown versions of documentation pages are available by appending `.md` to the page URL.45Token counting lets you determine how many input tokens a request will use before you send it to the model. Use it to:67- **Optimize prompts** to fit within context limits8- **Estimate costs** before making API calls9- **Route requests** based on size (for example, smaller prompts to faster models)10- **Avoid surprises** with images and files—no more character-based estimation1112The [input token count endpoint](https://developers.openai.com/api/reference/resources/responses/subresources/input_tokens/methods/count) accepts the same input format as the [Responses API](https://developers.openai.com/api/reference/resources/responses/methods/create). Pass text, messages, images, files, tools, or conversations—the API returns the exact count the model will receive.1314The count includes formatting tokens used to represent request structure, such as message roles and boundaries. These tokens might not appear in the text or fields you tokenize locally.1516## Why use the token counting API?1718Local tokenizers like [tiktoken](https://github.com/openai/tiktoken) work for plain text, but they have limitations:1920- **Images and files** are not supported—estimates like `characters / 4` are inaccurate21- **Tools and schemas** add tokens that are hard to count locally22- **Model-specific behavior** can change tokenization (for example, reasoning, caching)2324The token counting API handles all of these. Use the same payload you would send to `responses.create` and get an accurate count. Then plug the result into your message validation or cost estimation flow.2526## Count tokens in basic messages2728Simple text input2930```javascript31import OpenAI from "openai";3233const client = new OpenAI();3435const response = await client.responses.inputTokens.count({36 model: "gpt-6-astra",37 input: "Tell me a joke.",38});3940console.log(response.input_tokens);41```4243```python44from openai import OpenAI4546client = OpenAI()4748response = client.responses.input_tokens.count(49 model="gpt-6-astra", input="Tell me a joke."50)51print(response.input_tokens)52```5354```go55package main5657import (58 "context"59 "fmt"6061 "github.com/openai/openai-go/v3"62 "github.com/openai/openai-go/v3/responses"63)6465func main() {66 client := openai.NewClient()67 count, err := client.Responses.InputTokens.Count(context.Background(), responses.InputTokenCountParams{68 Model: openai.String("gpt-6-astra"),69 Input: responses.InputTokenCountParamsInputUnion{OfString: openai.String("Tell me a joke.")},70 })71 if err != nil {72 panic(err)73 }74 fmt.Println(count.InputTokens)75}76```7778```java79import com.openai.client.OpenAIClient;80import com.openai.client.okhttp.OpenAIOkHttpClient;81import com.openai.models.responses.inputtokens.InputTokenCountParams;8283var count =84 client85 .responses()86 .inputTokens()87 .count(88 InputTokenCountParams.builder()89 .model("gpt-6-astra")90 .input("Tell me a joke.")91 .build());9293System.out.println(count.inputTokens());94```9596```ruby97require "openai"9899client = OpenAI::Client.new100101count = client.responses.input_tokens.count(102 model: "gpt-6-astra",103 input: "Tell me a joke."104)105106puts(count.input_tokens)107```108109```bash110curl https://api.openai.com/v1/responses/input_tokens \111 -H "Authorization: Bearer $OPENAI_API_KEY" \112 -H "Content-Type: application/json" \113 -d '{114 "model": "gpt-6-astra",115 "input": "Tell me a joke."116 }'117```118119```bash120openai responses:input-tokens count \121 --model gpt-6-astra \122 --input "Tell me a joke." \123 --raw-output \124 --transform input_tokens125```126127128## Count tokens in conversations129130Multi-turn conversation131132```javascript133import OpenAI from "openai";134135const client = new OpenAI();136137const response = await client.responses.inputTokens.count({138 model: "gpt-6-astra",139 input: [140 { role: "user", content: "What is 2 + 2?" },141 { role: "assistant", content: "2 + 2 equals 4." },142 { role: "user", content: "What about 3 + 3?" },143 ],144});145146console.log(response.input_tokens);147```148149```python150from openai import OpenAI151152client = OpenAI()153154response = client.responses.input_tokens.count(155 model="gpt-6-astra",156 input=[157 {"role": "user", "content": "What is 2 + 2?"},158 {"role": "assistant", "content": "2 + 2 equals 4."},159 {"role": "user", "content": "What about 3 + 3?"},160 ],161)162print(response.input_tokens)163```164165```go166package main167168import (169 "context"170 "fmt"171172 "github.com/openai/openai-go/v3"173 "github.com/openai/openai-go/v3/responses"174)175176func main() {177 client := openai.NewClient()178 input := []responses.ResponseInputItemUnionParam{179 responses.ResponseInputItemParamOfMessage("What is 2 + 2?", responses.EasyInputMessageRoleUser),180 responses.ResponseInputItemParamOfMessage("2 + 2 equals 4.", responses.EasyInputMessageRoleAssistant),181 responses.ResponseInputItemParamOfMessage("What about 3 + 3?", responses.EasyInputMessageRoleUser),182 }183 count, err := client.Responses.InputTokens.Count(context.Background(), responses.InputTokenCountParams{184 Model: openai.String("gpt-6-astra"),185 Input: responses.InputTokenCountParamsInputUnion{OfResponseInputItemArray: input},186 })187 if err != nil {188 panic(err)189 }190 fmt.Println(count.InputTokens)191}192```193194```java195import com.openai.client.OpenAIClient;196import com.openai.client.okhttp.OpenAIOkHttpClient;197import com.openai.models.responses.EasyInputMessage;198import com.openai.models.responses.ResponseInputItem;199import com.openai.models.responses.inputtokens.InputTokenCountParams;200import java.util.List;201202var count =203 client204 .responses()205 .inputTokens()206 .count(207 InputTokenCountParams.builder()208 .model("gpt-6-astra")209 .inputOfResponseInputItems(210 List.of(211 ResponseInputItem.ofEasyInputMessage(212 EasyInputMessage.builder()213 .role(EasyInputMessage.Role.USER)214 .content("What is 2 + 2?")215 .build()),216 ResponseInputItem.ofEasyInputMessage(217 EasyInputMessage.builder()218 .role(EasyInputMessage.Role.ASSISTANT)219 .content("2 + 2 equals 4.")220 .build()),221 ResponseInputItem.ofEasyInputMessage(222 EasyInputMessage.builder()223 .role(EasyInputMessage.Role.USER)224 .content("What about 3 + 3?")225 .build())))226 .build());227228System.out.println(count.inputTokens());229```230231```ruby232require "openai"233234client = OpenAI::Client.new235conversation = [236 {237 role: :user,238 content: "What is 2 + 2?"239 },240 {241 role: :assistant,242 content: "2 + 2 equals 4."243 },244 {245 role: :user,246 content: "What about 3 + 3?"247 }248]249250count = client.responses.input_tokens.count(251 model: "gpt-6-astra",252 input: conversation253)254255puts(count.input_tokens)256```257258```bash259curl https://api.openai.com/v1/responses/input_tokens \260 -H "Authorization: Bearer $OPENAI_API_KEY" \261 -H "Content-Type: application/json" \262 -d '{263 "model": "gpt-6-astra",264 "input": [265 {"role": "user", "content": "What is 2 + 2?"},266 {"role": "assistant", "content": "2 + 2 equals 4."},267 {"role": "user", "content": "What about 3 + 3?"}268 ]269 }'270```271272```bash273openai responses:input-tokens count \274 --raw-output \275 --transform input_tokens <<'YAML'276model: gpt-6-astra277input:278 - role: user279 content: What is 2 + 2?280 - role: assistant281 content: 2 + 2 equals 4.282 - role: user283 content: What about 3 + 3?284YAML285```286287288## Count tokens with instructions289290Input with system instructions291292```javascript293import OpenAI from "openai";294295const client = new OpenAI();296297const response = await client.responses.inputTokens.count({298 model: "gpt-6-astra",299 instructions: "You are a helpful assistant that explains concepts simply.",300 input: "Explain quantum computing in one sentence.",301});302303console.log(response.input_tokens);304```305306```python307from openai import OpenAI308309client = OpenAI()310311response = client.responses.input_tokens.count(312 model="gpt-6-astra",313 instructions="You are a helpful assistant that explains concepts simply.",314 input="Explain quantum computing in one sentence.",315)316print(response.input_tokens)317```318319```go320package main321322import (323 "context"324 "fmt"325326 "github.com/openai/openai-go/v3"327 "github.com/openai/openai-go/v3/responses"328)329330func main() {331 client := openai.NewClient()332 count, err := client.Responses.InputTokens.Count(context.Background(), responses.InputTokenCountParams{333 Model: openai.String("gpt-6-astra"),334 Instructions: openai.String("You are a helpful assistant that explains concepts simply."),335 Input: responses.InputTokenCountParamsInputUnion{OfString: openai.String("Explain quantum computing in one sentence.")},336 })337 if err != nil {338 panic(err)339 }340 fmt.Println(count.InputTokens)341}342```343344```java345import com.openai.client.OpenAIClient;346import com.openai.client.okhttp.OpenAIOkHttpClient;347import com.openai.models.responses.inputtokens.InputTokenCountParams;348349var count =350 client351 .responses()352 .inputTokens()353 .count(354 InputTokenCountParams.builder()355 .model("gpt-6-astra")356 .input("Explain quantum computing in one sentence.")357 .instructions("You are a helpful assistant that explains concepts simply.")358 .build());359360System.out.println(count.inputTokens());361```362363```ruby364require "openai"365366client = OpenAI::Client.new367368count = client.responses.input_tokens.count(369 model: "gpt-6-astra",370 instructions: "You are a helpful assistant that explains concepts simply.",371 input: "Explain quantum computing in one sentence."372)373374puts(count.input_tokens)375```376377```bash378curl https://api.openai.com/v1/responses/input_tokens \379 -H "Authorization: Bearer $OPENAI_API_KEY" \380 -H "Content-Type: application/json" \381 -d '{382 "model": "gpt-6-astra",383 "instructions": "You are a helpful assistant that explains concepts simply.",384 "input": "Explain quantum computing in one sentence."385 }'386```387388```bash389openai responses:input-tokens count \390 --raw-output \391 --transform input_tokens <<'YAML'392model: gpt-6-astra393instructions: You are a helpful assistant that explains concepts simply.394input: Explain quantum computing in one sentence.395YAML396```397398399## Count tokens with images400401Images consume tokens based on size and detail level. The token counting API returns the exact count—no guesswork.402403Input with an image404405```javascript406import OpenAI from "openai";407408const client = new OpenAI();409410const response = await client.responses.inputTokens.count({411 model: "gpt-6-astra",412 input: [413 {414 role: "user",415 content: [416 {417 type: "input_image",418 image_url: "https://example.com/chart.png",419 detail: "auto",420 },421 { type: "input_text", text: "Summarize this chart." },422 ],423 },424 ],425});426427console.log(response.input_tokens);428```429430```python431from openai import OpenAI432433client = OpenAI()434435# Use file_id from uploaded file, or image_url for a URL436response = client.responses.input_tokens.count(437 model="gpt-6-astra",438 input=[439 {440 "role": "user",441 "content": [442 {443 "type": "input_image",444 "image_url": "https://example.com/chart.png",445 },446 {"type": "input_text", "text": "Summarize this chart."},447 ],448 }449 ],450)451print(response.input_tokens)452```453454```go455package main456457import (458 "context"459 "fmt"460461 "github.com/openai/openai-go/v3"462 "github.com/openai/openai-go/v3/responses"463)464465func main() {466 client := openai.NewClient()467 input := []responses.ResponseInputItemUnionParam{468 responses.ResponseInputItemParamOfMessage(469 responses.ResponseInputMessageContentListParam{470 {OfInputImage: &responses.ResponseInputImageParam{ImageURL: openai.String("https://example.com/chart.png"), Detail: responses.ResponseInputImageDetailAuto}},471 {OfInputText: &responses.ResponseInputTextParam{Text: "Summarize this chart."}},472 },473 responses.EasyInputMessageRoleUser,474 ),475 }476 count, err := client.Responses.InputTokens.Count(context.Background(), responses.InputTokenCountParams{477 Model: openai.String("gpt-6-astra"),478 Input: responses.InputTokenCountParamsInputUnion{OfResponseInputItemArray: input},479 })480 if err != nil {481 panic(err)482 }483 fmt.Println(count.InputTokens)484}485```486487```java488import com.openai.client.OpenAIClient;489import com.openai.client.okhttp.OpenAIOkHttpClient;490import com.openai.models.responses.ResponseInputImage;491import com.openai.models.responses.ResponseInputItem;492import com.openai.models.responses.inputtokens.InputTokenCountParams;493import java.util.List;494495var count =496 client497 .responses()498 .inputTokens()499 .count(500 InputTokenCountParams.builder()501 .model("gpt-6-astra")502 .inputOfResponseInputItems(503 List.of(504 ResponseInputItem.ofMessage(505 ResponseInputItem.Message.builder()506 .role(ResponseInputItem.Message.Role.USER)507 .addContent(508 ResponseInputImage.builder()509 .detail(ResponseInputImage.Detail.AUTO)510 .imageUrl(511 "https://api.nga.gov/iiif/a2e6da57-3cd1-4235-b20e-95dcaefed6c8/full/!800,800/0/default.jpg")512 .build())513 .addInputTextContent("Summarize this chart.")514 .build())))515 .build());516517System.out.println(count.inputTokens());518```519520```ruby521require "openai"522523client = OpenAI::Client.new524525count = client.responses.input_tokens.count(526 model: "gpt-6-astra",527 input: [528 {529 role: :user,530 content: [531 {532 type: :input_image,533 image_url: "https://api.nga.gov/iiif/a2e6da57-3cd1-4235-b20e-95dcaefed6c8/full/!800,800/0/default.jpg",534 detail: :auto535 },536 {537 type: :input_text,538 text: "Summarize this chart."539 }540 ]541 }542 ]543)544545puts(count.input_tokens)546```547548```bash549curl https://api.openai.com/v1/responses/input_tokens \550 -H "Authorization: Bearer $OPENAI_API_KEY" \551 -H "Content-Type: application/json" \552 -d '{553 "model": "gpt-6-astra",554 "input": [{555 "role": "user",556 "content": [557 {"type": "input_image", "image_url": "https://example.com/chart.png"},558 {"type": "input_text", "text": "Summarize this chart."}559 ]560 }]561 }'562```563564```bash565openai responses:input-tokens count \566 --raw-output \567 --transform input_tokens <<'YAML'568model: gpt-6-astra569input:570 - role: user571 content:572 - type: input_image573 image_url: https://example.com/chart.png574 - type: input_text575 text: Summarize this chart.576YAML577```578579580You can use `file_id` (from the [Files API](https://developers.openai.com/api/reference/resources/files)) or `image_url` (a URL or base64 data URL). See [images and vision](https://developers.openai.com/api/docs/guides/images-vision) for details.581582## Count tokens with tools583584Tool definitions (function schemas, MCP servers, etc.) add tokens to the context. Count them together with your input:585586Input with function tools587588```javascript589import OpenAI from "openai";590591const client = new OpenAI();592593const response = await client.responses.inputTokens.count({594 model: "gpt-6-astra",595 tools: [596 {597 type: "function",598 name: "get_weather",599 description: "Get the current weather in a location",600 strict: true,601 parameters: {602 type: "object",603 properties: { location: { type: "string" } },604 required: ["location"],605 additionalProperties: false,606 },607 },608 ],609 input: "What is the weather in San Francisco?",610});611612console.log(response.input_tokens);613```614615```python616from openai import OpenAI617618client = OpenAI()619620response = client.responses.input_tokens.count(621 model="gpt-6-astra",622 tools=[623 {624 "type": "function",625 "name": "get_weather",626 "description": "Get the current weather in a location",627 "parameters": {628 "type": "object",629 "properties": {"location": {"type": "string"}},630 "required": ["location"],631 },632 }633 ],634 input="What is the weather in San Francisco?",635)636print(response.input_tokens)637```638639```go640package main641642import (643 "context"644 "fmt"645646 "github.com/openai/openai-go/v3"647 "github.com/openai/openai-go/v3/responses"648)649650func main() {651 client := openai.NewClient()652 parameters := map[string]any{653 "type": "object",654 "properties": map[string]any{655 "location": map[string]any{"type": "string"},656 },657 "required": []string{"location"},658 "additionalProperties": false,659 }660 tool := responses.ToolParamOfFunction("get_weather", parameters, true)661 tool.OfFunction.Description = openai.String("Get the current weather in a location")662 count, err := client.Responses.InputTokens.Count(context.Background(), responses.InputTokenCountParams{663 Model: openai.String("gpt-6-astra"),664 Input: responses.InputTokenCountParamsInputUnion{OfString: openai.String("What is the weather in San Francisco?")},665 Tools: []responses.ToolUnionParam{tool},666 })667 if err != nil {668 panic(err)669 }670 fmt.Println(count.InputTokens)671}672```673674```java675import com.openai.client.OpenAIClient;676import com.openai.client.okhttp.OpenAIOkHttpClient;677import com.openai.core.JsonValue;678import com.openai.models.responses.FunctionTool;679import com.openai.models.responses.inputtokens.InputTokenCountParams;680import java.util.List;681import java.util.Map;682683var count =684 client685 .responses()686 .inputTokens()687 .count(688 InputTokenCountParams.builder()689 .model("gpt-6-astra")690 .input("What is the weather in San Francisco?")691 .addTool(692 FunctionTool.builder()693 .name("get_weather")694 .description("Get the current weather in a location")695 .strict(true)696 .parameters(697 FunctionTool.Parameters.builder()698 .putAdditionalProperty("type", JsonValue.from("object"))699 .putAdditionalProperty(700 "properties",701 JsonValue.from(702 Map.of("location", Map.of("type", "string"))))703 .putAdditionalProperty(704 "required", JsonValue.from(List.of("location")))705 .putAdditionalProperty(706 "additionalProperties", JsonValue.from(false))707 .build())708 .build())709 .build());710711System.out.println(count.inputTokens());712```713714```ruby715require "openai"716717client = OpenAI::Client.new718719count = client.responses.input_tokens.count(720 model: "gpt-6-astra",721 input: "What is the weather in San Francisco?",722 tools: [723 {724 type: :function,725 name: "get_weather",726 description: "Get the current weather in a location",727 strict: true,728 parameters: {729 type: "object",730 properties: { location: { type: "string" } },731 required: ["location"],732 additionalProperties: false733 }734 }735 ]736)737738puts(count.input_tokens)739```740741```bash742curl https://api.openai.com/v1/responses/input_tokens \743 -H "Authorization: Bearer $OPENAI_API_KEY" \744 -H "Content-Type: application/json" \745 -d '{746 "model": "gpt-6-astra",747 "tools": [{748 "type": "function",749 "name": "get_weather",750 "description": "Get the current weather in a location",751 "parameters": {752 "type": "object",753 "properties": {"location": {"type": "string"}},754 "required": ["location"]755 }756 }],757 "input": "What is the weather in San Francisco?"758 }'759```760761```bash762openai responses:input-tokens count \763 --raw-output \764 --transform input_tokens <<'YAML'765model: gpt-6-astra766tools:767 - type: function768 name: get_weather769 description: Get the current weather in a location770 parameters:771 type: object772 properties:773 location:774 type: string775 required:776 - location777input: What is the weather in San Francisco?778YAML779```780781782## Count tokens with files783784[File inputs](https://developers.openai.com/api/docs/guides/file-inputs) (currently PDFs) are supported. Pass `file_id`, `file_url`, or `file_data` as you would for `responses.create`. The token count reflects the model’s full processed input.785786## Understand output token counts787788Reported output token usage includes all tokens generated by the model, not only the text visible in a response. The Responses API reports this total as `output_tokens`, while the Chat Completions API reports it as `completion_tokens`.789790Some models, including GPT-5 models, generate tokens used to format or delimit response channels, tool calls, and other message structure. These formatting tokens don't appear in message content or `logprobs`, and they aren't necessarily itemized separately in usage. As a result, the reported output or completion token count can be higher than the number of visible tokens or tokens included in `logprobs`, even when the reported `reasoning_tokens` value is `0`.791792The `max_output_tokens` and `max_completion_tokens` parameters limit all tokens generated by the model, including non-visible tokens. The number of non-visible tokens varies by model and response shape, so don't assume a fixed difference between reported usage and visible output. Leave headroom in these limits when you need a specific amount of visible output.793794## API reference795796For full parameters and response shape, see the [Count input tokens API reference](https://developers.openai.com/api/reference/resources/responses/subresources/input_tokens/methods/count). The endpoint is:797798```799POST /v1/responses/input_tokens800```801802The response includes `input_tokens` (integer) and `object: "response.input_tokens"`.