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.

bash
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.

Get API keyDocumentation

api.zukko.pro · fetch_*

Gateway vs direct provider billing for a startup · Zukko