This page puts the price of four models side by side, all called through one OpenAI-compatible base URL, https://api.tokenlab.sh/v1, with one API key. It also gives a short script so you can measure latency from your own location. TokenLab publishes this page, so check the numbers against the live pages. Prices are USD per 1 million tokens, read on 2026-11-11 from the TokenLab pricing API and, for OpenRouter, from the per-endpoint prices in its public API. On the Verified route, claude-sonnet-5-5 is $0.70 / $3.50 through 2026-11-30 and $0.85 / $4.25 from 2026-12-01. Prices move with each price window; read on 2026-11-11.
Price: TokenLab Verified vs list price
| Model | TokenLab Verified (in / out) | Official list price (in / out) | OpenRouter standard endpoint (in / out) |
|---|---|---|---|
gpt-6.1-terra | $0.30 / $1.50 | $1.00 / $5.00 | $1.00 / $5.00 |
claude-sonnet-5-5 | $0.70 / $3.50 through 2026-11-30; $0.85 / $4.25 from 2026-12-01 | $2.00 / $10.00 | $2.00 / $10.00 |
grok-4.7 | $1.00 / $3.00 | $2.00 / $6.00 | $2.00 / $6.00 |
gemini-3.8-flash | $0.375 / $1.875 | $0.75 / $3.75 | $0.75 / $3.75 |
Some prices depend on prompt size. Above 272K input tokens, gpt-6.1-terra costs $0.60 / $2.25 on Verified, against $2.00 / $7.50 at list price. Above 200K input tokens, grok-4.7 costs $2.00 / $6.00 on Verified, against $4.00 / $12.00 at list price. The table shows the standard tier for both.
The OpenRouter column is the price of its standard direct-provider endpoint, read from its endpoint lists. OpenRouter also lists other endpoints for the same model: cheaper flex endpoints for some, and dearer priority and regional endpoints. For example, its flex endpoint for gemini-3.8-flash is $0.375 / $1.875, the same as TokenLab Verified, and its flex endpoint for gpt-6.1-terra is $0.50 / $2.50. Flex endpoints cost less and have lower processing priority (see its service tiers page), so compare like with like. TokenLab bills every request at the standard tier. OpenRouter passes provider prices through with no markup and charges a fee when you buy credits (5.5% on its Standard plan, see its pricing page). TokenLab charges no fee when you add credit.
Verified is TokenLab's lower-priced route. Official is priced at the maker's list price. See the delivery tiers guide. Not every model has a Verified price. For example, deepseek-v4.1-flash is billed at the maker's price, so it is not in the table.
Call all of them with one loop
from openai import OpenAI
client = OpenAI(
api_key="YOUR_TOKENLAB_KEY",
base_url="https://api.tokenlab.sh/v1",
)
for model in ["gpt-6.1-terra", "claude-sonnet-5-5", "grok-4.7", "gemini-3.8-flash"]:
resp = client.chat.completions.create(
model=model,
messages=[{"role": "user", "content": "One sentence on HTTP/2."}],
)
print(model, resp.choices[0].message.content)
Only the model string changes. Use the IDs as listed in the TokenLab model catalog.
Measure latency from your own location
Latency depends on where your client runs, the prompt, the output length and the time of day, so a number from someone else's test may not match yours. Measure three times for each request:
- First chunk: the first streamed chunk of any kind.
- First answer text: the first chunk that contains answer text. If a model streams reasoning before the answer, this arrives later than the first chunk.
- Finished: the end of the stream.
This script runs each model 20 times with streaming on and prints the median (p50) and the 95th percentile (p95) in milliseconds:
import statistics
import time
from openai import OpenAI
client = OpenAI(api_key="YOUR_TOKENLAB_KEY", base_url="https://api.tokenlab.sh/v1")
MODELS = ["gpt-6.1-terra", "claude-sonnet-5-5", "grok-4.7", "gemini-3.8-flash"]
PROMPT = "Write about 120 words on HTTP/2."
RUNS = 20
def timed_run(model):
start = time.perf_counter()
first_chunk = None
first_text = None
stream = client.chat.completions.create(
model=model,
messages=[{"role": "user", "content": PROMPT}],
stream=True,
)
for chunk in stream:
elapsed = (time.perf_counter() - start) * 1000
if first_chunk is None:
first_chunk = elapsed
if first_text is None and chunk.choices and chunk.choices[0].delta.content:
first_text = elapsed
return first_chunk, first_text, (time.perf_counter() - start) * 1000
def p50_p95(values):
if not values:
return "none"
p95 = statistics.quantiles(values, n=20)[18] if len(values) > 1 else values[0]
return round(statistics.median(values)), round(p95)
for model in MODELS:
runs = [timed_run(model) for _ in range(RUNS)]
chunks = [r[0] for r in runs if r[0] is not None]
texts = [r[1] for r in runs if r[1] is not None]
totals = [r[2] for r in runs]
print(model)
print(" first chunk (p50, p95):", p50_p95(chunks))
print(" first answer text (p50, p95):", p50_p95(texts))
print(" finished (p50, p95):", p50_p95(totals))
print(" runs with answer text:", len(texts), "of", RUNS)
How to read the result:
- With 20 runs, p95 is a rough guide only. Use more runs for a decision.
- A run can end with no answer text. The last line counts these runs, so you can see how often it happens.
- Run the test from the region and at the time of day where your users send traffic. A single window is one sample of many.
How to test it
Add $5 to $10 of balance, point one non-critical job at the endpoint, and compare cost per finished task and error rate with your current setup. If the numbers do not work for you, stop; nothing else changes. Create a key or see live pricing. Prices can change; the live pages win.