Why a startup wants a gateway instead of billing each provider directly
Five providers means five bills, five currencies, five API shapes. What changes when one key and one balance sit behind all of it.
5 min · · Updated · бизнес
An early-stage startup testing several models at once usually ends up in the same place: a separate signup, a separate payment method, a separate request format for every provider. Claude expects /v1/messages with an anthropic-version header, OpenAI expects /v1/chat/completions, and everyone else has their own quirks. A gateway with one fetch_... key removes that duplication not by magically merging providers, but by serving both of the two most common formats — Anthropic-compatible and OpenAI-compatible — from one place on one balance.
One key, two protocols, the whole model lineup
The key works with both POST /v1/messages (for clients like Claude Code or the Anthropic SDK) and POST /v1/chat/completions or POST /v1/responses (for Cursor, Codex, the OpenAI SDK). That means A/B-testing claude-opus-5-5 against gpt-5.6-sol on a real task doesn't require rewriting client code for a second request format — only the address and request body change, not the infrastructure around keys and billing.
Paying without opening an account in another jurisdiction
Direct billing with Anthropic or OpenAI is usually tied to a card issued in a supported country, which is its own administrative project for a team without a foreign legal entity. Here the options are SBP, a bank card via PayPear, crypto, and — as of 2026-09-16 — a foreign Mastercard EU card via Fride (about 13% commission, amounts from $2 to $594). The minimum top-up is $1. For a one- or two-person team at the start, that's the difference between "set up in ten minutes" and "find someone to borrow a foreign card from."
Per-key limits as budget control, not a restriction
Every key can carry a daily and monthly dollar spending limit and a list of allowed models, configured on that key's page in the dashboard. In practice this maps cleanly onto roles: a key for a junior developer scoped to glm-5.3-flash with a $5 daily cap, a key for the core team with claude-opus-5-5 and no model restrictions. One bad prompt stuck in a loop, or a forgotten cron job, burns through a single key's budget under this setup instead of the company's entire balance.
Balance is checked before the request reaches a model
A 402 — {"error":{"message":"Insufficient balance","code":"insufficient_balance"}} — comes back before the request goes anywhere near a provider. That means a broken deploy spamming requests against a zero balance spends nothing until the balance is topped up. For an early-stage startup, where deploys happen often and not always cleanly, that's a concrete guard against a surprise bill, not an abstract nicety.
Tracking spend without five separate dashboards
GET /v1/usage returns a cursor-paginated history of charges (next_cursor; fields created_at, model, input_tokens, output_tokens, total_tokens, cost_cents in fractional cents) — pull it into your own spreadsheet or dashboard instead of logging into five different provider consoles in turn. The history covers the whole account, all keys together — there's no per-key filter. At the level of a single request, a regular (non-streaming) response carries X-Zukko-Cost-Micros (that request's cost in micro-dollars, where 1,000,000 = $1) and X-Fetch-Balance-Cents (the balance left after the charge — despite the name, also in micro-dollars; the exact balance in cents comes from GET /v1/balance) — enough to attribute a request's cost to a specific customer, feature, or experiment on the fly, with no separate trip to billing. Streamed responses (stream: true) don't carry these headers — for those, check spend in the dashboard, /v1/usage or /v1/balance.
What happens when the catalogue changes
Models get switched off and replaced, and that's a normal part of an API's lifecycle. The difference is how the client finds out: a disabled model answers 503 with the code model_disabled, and the current list is always available at GET https://api.zukko.pro/v1/models (or on the Models page in the dashboard). There's no need to watch a provider's changelog separately — once that error shows up in the production logs, it's clear what to change in the config.
Idempotency as part of billing hygiene
The Idempotency-Key header returns the same response to a repeated request with the same key and the same body within 24 hours, without charging again. The key is set per logical request — unique to that request and identical across its retries; it's never regenerated on a retry. It works for POST /v1/chat/completions, /v1/messages and /v1/responses. For a startup where retry logic on network drops tends to get written quickly and without much care, that's the difference between a customer paying twice for the same answer and a retry costing nothing.
The referral program as a side source of offset
10% of top-ups from invited users — if a startup is already telling other founders what it uses, a referral link offsets part of its own API spend for no extra effort.
Service status in your own monitoring
GET https://api.zukko.pro/api/status returns a public JSON with model status, no key required — drop it into whatever status page or health check the team already runs for its own services, instead of manually checking whether the provider is alive when a production request fails. For a startup with one person on call for everything, that's one fewer source of uncertainty at three in the morning: if /api/status answers fine and requests still fail, the problem is local, not on the gateway's side.
Support without a separate ticket tracker
At an early stage, setting up a full escalation process with each provider just to ask one billing question is overhead. Support here runs through Telegram @zukkopro, no form, no multi-day wait for an email reply — for a startup where downtime is counted in hours, that's also part of the operational savings, not a minor detail.
curl https://api.zukko.pro/v1/balance \
-H "Authorization: Bearer fetch_your_key"
curl "https://api.zukko.pro/v1/usage?limit=50" \
-H "Authorization: Bearer fetch_your_key"None of this replaces a direct relationship with a provider once a company grows to a volume where negotiating custom terms makes sense. But for a team still choosing between models and counting every dollar of infrastructure budget, one key, one balance, and predictable limits remove an administrative layer that would otherwise eat time better spent on the product.
zukko
Pay 25×
less
for Claude Code & ChatGPT
One fetch_* key and base URL api.zukko.pro — for Cursor, Claude Code, Codex, and any SDK.
Related articles
- AI for testers: test cases, checklists and bug reportsHow a QA engineer can use a model for test cases, checklists and bug reports, check coverage, and avoid requirements the model made up.
- Anonymizing data before sending it to a neural network: a practical wayYou do not have to send personal data to a model for it to process a document. How to replace it with labels, restore it in the answer and check that nothing leaked.
- A neural network for HR: job posts, candidate emails and resume reviewA model can draft job posts and emails and do a first-pass resume review. What to hand over, how to treat candidates' personal data and how to prevent biased decisions.
- An AI agent for 1C: which tasks to automate and howAn agent around 1C answers questions from data, drafts documents and looks for anomalies. We cover the scenarios, the HTTP-service architecture and safety measures.