One endpoint, many models: switching between GPT, Claude and DeepSeek and logging what every call costs A developer built a small Python harness that routes requests to GPT, Claude and DeepSeek through a single OpenAI-format Chat Completions endpoint, using the openai SDK's configurable base_url and per-model pricing tables to log the dollar cost of every call. The harness computes spend from the usage object's prompt, cached and completion token counts, and the developer notes that tokenizers and default thinking modes make naive per-token estimates unreliable — Anthropic's Claude 4.7+ tokenizer yields roughly 30% more tokens for the same text, and DeepSeek's Flash model runs in thinking mode by default. A sample 2,000-token prompt with a 500-token answer costs $0.00375 on GPT-5.4 mini, $0.009 on Claude Sonnet 5 and $0.0012 on DeepSeek Flash at peak hours, per list prices checked October 23, 2026. The OpenAI Chat Completions format has quietly become the common plug of the LLM world. DeepSeek documents an OpenAI-format base URL for its own API, most gateways speak it, and the official openai Python SDK lets you point base url anywhere. So switching from GPT to Claude to DeepSeek looks like changing one string. It mostly is. But "mostly" hides the part that shows up on your invoice: the same prompt is a different number of tokens on different models, and some models think before answering and bill you for it. Below is a small harness for comparing models on real prompts instead of on vibes. Keep the endpoint and key in environment variables and treat the model as a plain argument. python import os from openai import OpenAI client = OpenAI base url=os.environ "LLM BASE URL" , provider or gateway, e.g. https://api.deepseek.com api key=os.environ "LLM API KEY" , def ask model: str, prompt: str, extra : resp = client.chat.completions.create model=model, messages= {"role": "user", "content": prompt} , extra, return resp.choices 0 .message.content, resp.usage One thing does change between endpoints: model IDs. Talking to OpenAI directly you write gpt-5.4-mini ; many gateways namespace it as openai/gpt-5.4-mini . Keep IDs in config, not scattered through the code. usage into money Every response carries a usage object, and that is the only number worth trusting. In the OpenAI format, prompt tokens already includes cached tokens broken out in prompt tokens details.cached tokens , and completion tokens already includes reasoning tokens broken out in completion tokens details.reasoning tokens . So the math is: fresh input at the input price, cached input at the cached price, all completion tokens at the output price. Here are list prices checked on October 23, 2026: PRICES = { USD per 1M tokens, provider list prices as of 2026-10-23 "openai/gpt-5.4-mini": {"in": 0.75, "cached": 0.075, "out": 4.50}, "anthropic/claude-sonnet-5": {"in": 2.00, "cached": 0.20, "out": 10.00}, "deepseek/deepseek-v4-flash": {"in": 0.30, "cached": 0.006, "out": 1.20}, peak hours } def cost usd model: str, usage - float: p = PRICES model details = getattr usage, "prompt tokens details", None cached = getattr details, "cached tokens", 0 or 0 if details else 0 fresh = usage.prompt tokens - cached return fresh p "in" + cached p "cached" + usage.completion tokens p "out" / 1 000 000 A quick sanity check with a 2,000-token prompt and a 500-token answer: GPT-5.4 mini comes to $0.00375 per call, Claude Sonnet 5 to $0.009, DeepSeek Flash to $0.0012 at peak hours. Over 10,000 calls that is $37.50, $90 and $12. Those numbers are almost certainly wrong for your workload. The 2,000 tokens will not be 2,000 on every model: Anthropic says the tokenizer in Claude 4.7 and later produces roughly 30% more tokens for the same text. And the 500-token answer assumes no hidden reasoning, while DeepSeek's docs say its Flash model runs in thinking mode by default. The table also skips Anthropic's cache writes 1.25x the input price and DeepSeek's off-peak rates half of peak; peak is 01:00–04:00 and 06:00–10:00 UTC on weekdays . Add fields if they matter to you. Take 20 to 50 prompts from real traffic, run each through every candidate model, and write one CSV row per call: python import csv, time prompts = line.strip for line in open "prompts.txt", encoding="utf-8" if line.strip with open "compare.csv", "w", newline="", encoding="utf-8" as f: w = csv.writer f w.writerow "model", "prompt tokens", "completion tokens", "reasoning tokens", "seconds", "usd", "answer" for model in PRICES: for prompt in prompts: t0 = time.perf counter text, usage = ask model, prompt dt = time.perf counter - t0 cd = getattr usage, "completion tokens details", None reasoning = getattr cd, "reasoning tokens", 0 or 0 if cd else 0 w.writerow model, usage.prompt tokens, usage.completion tokens, reasoning, round dt, 2 , round cost usd model, usage , 6 , text Before judging quality, look at three columns. prompt tokens shows the tokenizer difference on your own text, reasoning tokens shows which models think when you did not ask them to, and usd gives a real cost per call. The answer sits in the same row, so you judge quality next to price. Parameters are less portable than the endpoint. Some models reject options that others accept, reasoning models especially around temperature and output limits. Keep a small overrides dict per model and pass it through extra instead of sprinkling if model.startswith ... around. Caching differs too: OpenAI caches prefixes automatically, Anthropic needs cache control . If cached tokens stays at zero on a long system prompt, you pay full price for it on every call. Prices move. Anthropic's pricing page currently notes that Claude Sonnet 5's launch price, announced as introductory, has become the standard one. Date your price table and re-check it before you trust last month's numbers. And if you go through a gateway, its bill is the truth, not the list price. List prices are fine for comparing models; for real spend, reconcile against the gateway's usage export. Under 50 lines, and arguments about which model is cheaper turn into a CSV you can sort. Disclosure: I'm building Heli getheli.ru , an OpenAI-compatible gateway for developers in Russia that bills in rubles. The code above works with it if you set LLM BASE URL=https://getheli.ru/v1 , but nothing here depends on it. This post was drafted with the help of an AI assistant and reviewed and edited by me.