Multiple projects, one account: staying organized
One account balance, five projects drawing from it. How to organize that so month-end shows who spent what, instead of one lump sum to puzzle over.
4 min · · Updated · API keys
A freelancer with three clients, an agency running parallel projects, a developer keeping work and personal code under one login — in every case there's one account balance and several sources of spend drawing on it. The problem doesn't start with the spending itself, it starts at month-end when it's unclear which project ate how much.
The balance is shared, the keys are not
GET /v1/balance returns the balance for the whole account — one number, no matter how many keys are issued or how many projects use them. But the daily and monthly spend limit in dollars, and the list of allowed models, are configured on a specific key's page under /app/api-keys — that's per-key, not per-account. That gives you a practical setup: one account, one shared balance for top-ups, but a separate key per project with its own limit.
curl https://api.zukko.pro/v1/balance \
-H "Authorization: Bearer fetch_any_key_on_this_account"It doesn't matter which of the account's keys you use to call /v1/balance — the number comes back the same, because the balance is shared.
Splitting spend across projects when the balance is shared
Since the balance is shared but limits are per-key, tracking "whose spend was this" takes two sources, not one:
- The
X-Zukko-Cost-MicrosandX-Fetch-Balance-Centsheaders on every regular (non-streaming) response — the cost of that specific request and the remaining account balance after it (both in microdollars, despite the "Cents" in the second one's name). Logged together with the key, they give you the per-project breakdown. GET /v1/usage— charge history for the whole account (all keys together, no per-key filter), with cursor pagination — for reconciling the overall total and for streaming requests, which carry no cost headers.
curl https://api.zukko.pro/v1/usage \
-H "Authorization: Bearer fetch_your_key"If each client or project gets its own key and you log X-Zukko-Cost-Micros separately per key, the total on client A's key at month-end is their bill — no need to split the account's overall spend proportionally by eyeballing it. If a client works through streaming requests (stream: true), those carry no headers — for strict separation, give that client a separate account.
A per-key limit protects against one project running away
If one project — say, a content-generation script for client B — suddenly loops and starts firing requests in bursts, and everything runs on one shared key, that hits the same balance feeding client A and client C too. With a separate key per project and a daily limit set on it, that script hits its own ceiling and stops with 429 key_daily_limit_reached, while the account balance backing the other keys stays untouched.
The allowed-model list keeps projects inside their own lane
If client A's contract fixes a budget around models like glm-5.3-flash, while client B pays for work on claude-opus-5-5, restricting the model list at the key level enforces that technically: client A's key physically cannot call the expensive model, even if that happens by mistake in the code. The attempt comes back as 403 model_not_allowed_for_key instead of an unexpected bill at the wrong rate.
Topping up is shared, spending is separate
Paying into the balance — via SBP, bank card (PayPear), crypto, or, since September 16, 2026, a foreign Mastercard EU card through Fride (about 13% fee, amounts $2–$594) — goes to the account as a whole, not to a specific key. That's convenient: no need to top up five times for five projects. But it's exactly why you shouldn't rely on remembering "whose payment was that last one" — all per-project reporting should run through your per-key logs of the cost headers (with /v1/usage for reconciling the overall total), not through the balance top-up history; top-ups themselves don't show up in /v1/usage.
The referral program when running several client projects
10% of what invited users top up gets credited to whoever invited them. If you're running several client projects and suggest they set up their own account instead of using your key, that's not just cleaner from a billing standpoint (each client gets their own limit and their own history) — it also earns a percentage of their top-ups through the referral program.
What this looks like in practice
For an agency with several clients: one account, one payment method, but:
export FETCH_KEY_CLIENT_A=fetch_... # $50/mo limit, glm-5.3-flash and gpt-5.6-luna only
export FETCH_KEY_CLIENT_B=fetch_... # $200/mo limit, claude-opus-5-5 allowed
export FETCH_KEY_INTERNAL=fetch_... # $10/day limit, for tests and demosEach key lives in its own project's environment variables, each limit is set for a specific contract, and the per-key sum of X-Zukko-Cost-Micros from your logs at month-end is already a ready-made client invoice, instead of a reason to manually re-split the account's overall spend.
Checking that the service itself is up shouldn't depend on any one key
If every project has its own key with its own limit, a question comes up: how do you check that the service itself is alive without tying that check to any single client's balance or limit. There's a public endpoint for exactly that, no key required — a JSON with model status:
curl https://api.zukko.pro/api/statusA shared monitoring script watching availability for every project at once can hit /api/status without depending on any client key — if it instead depended on one client's key and that client's limit ran out, the other projects' status would get misread as an outage. Separately, GET /v1/models also returns its list without a key — useful for confirming a given model is still in the catalog before digging into why one particular client's key came back with 404 model_not_found or 503 model_disabled.
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
- OpenAI API Keys in the Open: Why You Should Not Use ThemWhere free keys on GitHub come from, why using them is dangerous for you and for the owner, and how to protect your own key from the same leak.
- GLM API Errors: Why the Request Fails and How to Fix ItA wrong model id, an overflowing 128K context, the key, the balance, limits: the typical causes of GLM API errors and a quick way to find yours.
- xAI Grok API: Connecting Grok 4.7, Price and the 256K ContextHow to call grok-4.7 through an OpenAI-compatible API, what to do about the 256K context limit and what typical requests cost. Plus a comparison with Grok 4.6.
- This organization has been disabled in the Claude API: What to DoAn Anthropic key suddenly answers "organization has been disabled". What the error is, what to check, and how to move the SDK and Claude Code to another provider.