GreenTokens

Search

Search models, guides, docs and the FAQ.

API

Text

Chat Completions, Responses and Anthropic Messages, with streaming, tools, vision and caching.

Endpoints

Use whichever format your code already speaks. Every route also works without the /v1 prefix.

MethodPathFormat
POST/v1/chat/completionsOpenAI Chat Completions: streaming, tools, vision
POST/v1/responsesOpenAI Responses, with streaming
POST/v1/messagesAnthropic Messages: streaming, tools, prompt caching, extended thinking
POST/v1/messages/count_tokensAnthropic token counting. Free, never billed

Chat Completions

The OpenAI Chat Completions format. model is any text model ID from the models page; the response echoes the same ID.

curl https://api.greentokens.io/v1/chat/completions \
  -H "Authorization: Bearer $GREENTOKENS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gpt-6-sol",
    "messages": [
      {"role": "system", "content": "You are a concise assistant."},
      {"role": "user", "content": "Explain rate limiting in one sentence."}
    ],
    "max_tokens": 200
  }'

Streaming

Set stream: true to receive tokens as they're generated, as server-sent events. Token usage arrives on the final chunk.

stream = client.chat.completions.create(
    model="claude-sonnet-5",
    messages=[{"role": "user", "content": "Write a haiku about latency."}],
    stream=True,
)
for chunk in stream:
    if chunk.choices and chunk.choices[0].delta.content:
        print(chunk.choices[0].delta.content, end="", flush=True)
Long responses stay alive: if the model is slow to start, the stream sends keepalive comments instead of timing out. Most SDKs ignore them automatically.

Responses

The OpenAI Responses format, with input, instructions and output_text. Streaming works the same way.

response = client.responses.create(
    model="gpt-6-sol",
    instructions="Answer in one short paragraph.",
    input="What is a context window?",
)
print(response.output_text)

Anthropic Messages

The Anthropic Messages format. Point the Anthropic SDK at https://api.greentokens.io (no /v1): the SDK adds the path itself. Errors on this route use the Anthropic error format.

from anthropic import Anthropic

client = Anthropic(base_url="https://api.greentokens.io", api_key="sk-gt-…")

message = client.messages.create(
    model="claude-opus-5-5",
    max_tokens=1024,
    system="You are a senior code reviewer.",
    messages=[{"role": "user", "content": "Review: def add(a, b): return a - b"}],
)
print(message.content[0].text)

Tool calling

Define functions the model can call. The response contains the call; your code runs it and sends the result back in a tool message. Tool use also works through Messages in the Anthropic format.

tools = [{
    "type": "function",
    "function": {
        "name": "get_weather",
        "description": "Current weather for a city",
        "parameters": {
            "type": "object",
            "properties": {"city": {"type": "string"}},
            "required": ["city"],
        },
    },
}]

response = client.chat.completions.create(
    model="gpt-6-sol",
    messages=[{"role": "user", "content": "Is it raining in Lisbon?"}],
    tools=tools,
)
call = response.choices[0].message.tool_calls[0]
print(call.function.name, call.function.arguments)  # get_weather {"city": "Lisbon"}

Images as input

Models that accept images take them as image_url parts, including data URLs. Filter by Text + image on the models page to see which ones.

Python
import base64

with open("chart.png", "rb") as f:
    image = base64.b64encode(f.read()).decode()

response = client.chat.completions.create(
    model="gpt-6-sol",
    messages=[{
        "role": "user",
        "content": [
            {"type": "text", "text": "What does this chart show?"},
            {"type": "image_url", "image_url": {"url": f"data:image/png;base64,{image}"}},
        ],
    }],
)
print(response.choices[0].message.content)

Prompt caching

Repeated input is billed at the lower cached-input price. Put the large, unchanging part of a prompt (system instructions, reference documents, tool definitions) first, and keep it byte-for-byte identical between calls.

  • Anthropic Messages: mark the reusable block with "cache_control": {"type": "ephemeral"}, as below.
  • OpenAI formats: caching of repeated prefixes is automatic. Check cached_tokens in the usage.
Python · Messages
message = client.messages.create(
    model="claude-sonnet-5",
    max_tokens=1024,
    system=[{
        "type": "text",
        "text": LONG_REFERENCE_DOCUMENT,  # the large, unchanging part
        "cache_control": {"type": "ephemeral"},
    }],
    messages=[{"role": "user", "content": "Summarise section 3."}],
)
print(message.usage.cache_read_input_tokens)  # > 0 once the cache is warm

Counting tokens

Estimate a request's input size before sending it. /v1/messages/count_tokens is free and never billed.

count = client.messages.count_tokens(
    model="claude-sonnet-5",
    messages=[{"role": "user", "content": "How many tokens is this?"}],
)
print(count.input_tokens)