Together AI API Multi-Tenant Guide: One Key, Many Customers, No Blast Radius
Every other integration guide assumes the traffic is yours. This one assumes it belongs to your customers — which means one of them can exhaust your Together AI quota, run up your invoice, or read another one's data, and every one of those failures arrives as a successful response.
📡 Monitor your APIs — know when they go down before your users do
Better Stack checks uptime every 30 seconds with instant Slack, email & SMS alerts. Free tier available.
Affiliate link — we may earn a commission at no extra cost to you
There is a specific moment where a Together AI integration stops being an integration and becomes a platform: the point at which the person whose prompt you are forwarding is not you. Before that moment, every hard problem is availability-shaped — is it up, did the call fail, how do I retry, where do I fail over. After it, a whole second category appears that none of those controls touch, because the adversary and the cost centre and the data owner are all your own users, and the provider sees exactly one customer: you.
That inversion is what makes multi-tenancy its own problem rather than a harder version of an existing one. A circuit breaker protects you from Together AI. A retry budget protects Together AI from you. Nothing in either protects your tenants from each other, and nothing in either notices when one of them is quietly the entire invoice.
Ranking the four risks by how much damage they do before anyone notices: cross-tenant data disclosure (silent, unbounded, and often discovered by the victim); cost blast radius (bounded by the billing cycle, discovered on the invoice); quota exhaustion (loud, but it looks like a provider outage and gets diagnosed as one); abuse of your endpoint as a free proxy (slow, and usually found by looking at cost). Confirm the platform is actually healthy at live Together AI status before you spend an afternoon debugging what turns out to be one tenant.
What the Provider Cannot See About Your Tenants
Start from the provider's point of view, because every gap in it is a control you have to build. Together AI sees one account, a set of keys, and a stream of requests. Here is what that view structurally cannot resolve, and what each blind spot costs you.
| What Together AI cannot distinguish | What it costs you | Who has to build the control |
|---|---|---|
| Which tenant a request belongs to | The invoice is a single number. Per-customer margin is unknowable, and so is which customer to talk to when one is unprofitable. | You, in the request path |
| Whether a burst is one tenant or all of them | A 429 arrives with no attribution, so the incident presents as a provider problem and is investigated as one. | You, in the request path |
| Whether a prompt is first-party or user-supplied | Content policy enforcement lands on your account. A tenant's violation is your suspension. | You, before the call |
| Whose data is in a retrieved context block | Cross-tenant disclosure with a 200 status. No error rate moves. | You, in your own storage layer |
| Whether a tenant is on a free trial | Unbounded spend from an account that will never pay. Trial abuse is a cost problem long before it is a fraud problem. | You, at admission |
| That a request came from your product at all | If your endpoint is reachable and unmetered, it is a free Together AI proxy for anyone who finds it. | You, at authentication |
Every row resolves to the same sentence: the provider is not a participant in your multi-tenancy. That is not a criticism of Together AI — it is the correct design for a wholesale API. It just means the entire mechanism lives on your side of the wire, and any plan that begins “we will use the provider's per-key limits” is skipping the part where you check whether those limits are per key.
The Isolation Ladder
Multi-tenant Together AI deployments sit on one of five rungs. Most teams believe they are one rung higher than they are, because attribution and isolation feel like the same thing until the first contention incident proves they are not.
| Rung | What it gives you | What still breaks |
|---|---|---|
| 1. One key, no tenant tag | Nothing. It ships fastest and it is where almost everyone starts. | Everything. You cannot answer “which customer” about cost, contention or abuse, ever, retroactively. |
| 2. One key, tenant id on every ledger row | Attribution. You can name the tenant behind any cost or burst, after the fact. | No enforcement. You watch the noisy neighbour in a dashboard while it happens. |
| 3. Rung 2 plus in-path per-tenant budgets | Enforcement. The first real rung: one tenant can no longer take the others down or run up an unbounded bill. | Data isolation is untouched. Caches, indexes and example selectors still cross tenants. |
| 4. Rung 3 plus tenant-scoped storage | Disclosure containment: cache keys, vector namespaces and prompt assembly all carry the tenant id. | Compliance ceiling. Everything still runs under your account, your DPA and your content-policy exposure. |
| 5. Bring-your-own-key | The tenant's traffic is billed to the tenant, limited by the tenant's quota, and governed by the tenant's agreement. | Support load and a new secret-management problem. Only worth it for enterprise tiers that ask for it. |
The jump that matters is 2 to 3. Rung 2 is where most production systems actually live, and it feels safe because the dashboard is informative — you can see the noisy tenant clearly. But a dashboard is a record of a decision you did not make. Rung 3 is the first rung where the system says no on its own, at 3am, without anyone reading anything.
Is It The Provider, Or Is It One Tenant?
A 429 storm caused by your busiest customer and a genuine Together AI degradation look identical from inside your own logs. An external monitor calling the API on a fixed, tiny schedule answers the question in seconds, because its traffic is not competing with anyone's.
Try Better Stack Free →Admission Control, In the Request Path
The control that does the work is small and unglamorous: before the outbound call, ask whether this tenant is allowed to make it. Two independent checks — a rate bucket and a concurrency cap — because they fail differently. A tenant can stay under any per-minute rate and still occupy your entire connection pool with long streaming requests, and a tenant can hold one connection and still burn a per-minute allowance in a loop.
// Per-tenant admission for Together AI. State lives in Redis so the budget
// holds across every process — a per-instance bucket silently multiplies
// the real limit by your instance count, which is the most common way
// this control is built and then does not work.
const TIERS = {
free: { rpm: 5, concurrent: 1, usdPerDay: 0.50 },
pro: { rpm: 60, concurrent: 4, usdPerDay: 25 },
enterprise: { rpm: 600, concurrent: 25, usdPerDay: 500 },
};
async function admit(tenant) {
const tier = TIERS[tenant.tier];
// 1. Rolling-window rate, not a counter reset on the minute boundary.
// A minute-boundary counter lets a tenant spend two full allowances
// back to back across the boundary.
const rate = await redis.eval(ROLLING_WINDOW_LUA,
['rate:' + tenant.id], [tier.rpm, 60, nowMs()]);
if (!rate.allowed) return deny('rate', rate.retryAfterMs);
// 2. Concurrency, held for the life of the request. Independent of rate:
// long streaming calls exhaust connections without moving the rate.
const slot = await acquireSlot('conc:' + tenant.id, tier.concurrent);
if (!slot) return deny('concurrency', 250);
// 3. Spend, priced at WRITE time from a dated rate table. Soft threshold
// degrades, hard threshold refuses — and the hard one is only ever
// applied to free and trial tiers.
const spentToday = await redis.get('spend:' + tenant.id + ':' + today());
if (spentToday >= tier.usdPerDay) {
if (tenant.tier === 'free') return deny('budget', null);
degradeToCheaperModel(tenant); // paid tiers degrade, never hard-fail
alertAccountOwner(tenant);
}
return { ok: true, slot };
}
// The sum of concurrent tenant allowances must sit BELOW the account
// ceiling. Tuning it to exactly 100% means normal variance produces 429s
// that look like a provider incident.Three details in there are the ones that get dropped and each has a characteristic failure. State in process memory rather than shared storage multiplies your effective limit by the instance count, so the control appears to work in staging with one instance and does nothing in production with twelve. A minute-boundary counter instead of a rolling window lets a tenant spend two full allowances back to back across the boundary. And a hard spend refusal applied to a paying customer converts a cost problem into a churn problem — degrade paid tiers, refuse free ones.
The Together AI Trap: Isolation That Works by Accident Until Two Tenants Agree
Together AI is a marketplace, and its rate limits are scoped per model rather than pooled across the account. That produces the most dangerous shape a multi-tenant system can have: isolation that appears to work and was never designed. While tenant A is on one open-weights model and tenant B is on another, they genuinely do not contend, every load test passes, and the absence of admission control looks like a decision that was correct. The day a model becomes popular and both tenants land on it, the isolation vanishes with no code change on your side and no incident on the provider's.
Anything model-scoped is a boundary you do not control, because tenants — or your own defaults, or a deprecation that migrates everyone onto the successor model — choose which side of it they sit on. Treat per-model limits as a happy accident that reduces the frequency of contention, never as the mechanism that prevents it. The admission control has to exist regardless, and the bucket key should be tenant plus model so you can see contention forming before it becomes a report.
The related marketplace hazard is that per-model limits and per-model pricing move independently and per model. A tenant that migrates from one model to another can multiply both their cost and their share of a ceiling in a single deploy, and neither the invoice nor the rate-limit headers will attribute the change to them unless the exact model id is on every ledger row.
Six Multi-Tenant Failures That Return HTTP 200
This is why multi-tenancy resists the monitoring you already have. Availability problems announce themselves with a status code; tenancy problems do not. Every row below is a successful response.
| What happened | What you observe | The signal that would have caught it |
|---|---|---|
| Cache keyed on prompt text serves tenant A's answer to tenant B | 200, and a suspiciously fast response | Cache-hit rate broken down by tenant pair; a hit across tenants should be structurally impossible, not rare |
| Retrieval query missing the tenant filter | 200, well-cited, confidently wrong ownership | A deploy-gating test asserting a cross-tenant query returns zero rows |
| Few-shot examples selected from recent traffic across all tenants | 200, and better output quality than before | Example-selector unit test with a required tenant argument; the quality gain is what stops anyone looking |
| One tenant consumes 90 percent of the account's token allowance | 200 for them, intermittent 429 for everyone else | Share-of-account-ceiling per tenant, alerting above a threshold well under 100 percent |
| A trial account scripts your endpoint as a free Together AI proxy | 200 forever, until the invoice | Per-tenant requests-per-active-session; a human and a script have entirely different pacing |
| A tenant's user content trips the provider's content policy | 200s, then an account-level warning aimed at you | Refusal and moderation-flag rate per tenant; a single tenant's spike is the whole account's risk |
The pattern across all six is that the request-level metrics you already collect — status code, latency, error rate — are blind to every one of them. Each requires a metric with a tenant dimension, which is the real argument for putting the tenant id on the ledger row long before you think you need it. You cannot add that dimension retroactively to traffic that has already happened.
One Provider Credential, Many People Who Can Reach It
Multi-tenant deployments accumulate keys: a production key, per-environment keys, per-tier keys, and eventually tenant-supplied ones. Shared, audited credential storage is what keeps a revocation from turning into a search.
Try 1Password Free →Data Isolation Is Not a Together AI Setting
Nothing in the Together AI API mixes one customer's data into another's response. Every real cross-tenant disclosure in an LLM product happens in code that runs before or after the call, in three places that are all optimisations someone added for good reasons.
- The response cache. Keyed on the prompt, it is correct for a single-tenant app and a disclosure channel for a multi-tenant one. The tenant id belongs in the key, including in the negative and error caches that get added later without a review.
- The retrieval index. A filter that a caller can forget will eventually be forgotten. Prefer a namespace per tenant, or a single query function that takes the tenant id as a required argument and builds the filter itself, with no code path that reaches the store directly.
- Prompt assembly. Few-shot examples mined from recent production traffic, summaries carried between turns, and any “similar past request” feature all move text between requests. If that text is user content, the selector needs a tenant argument for the same reason the index does.
There is also a contractual layer that outlives all three. Whatever data-retention and training posture you have agreed with Together AI applies to every tenant's content, because it is all your account. A tenant that needs stricter terms than the ones you hold cannot get them inside your account at any rung below bring-your-own-key — see the data privacy guidefor what those terms actually cover.
When Bring-Your-Own-Key Is Worth It
BYOK is the top rung and it is genuinely different in kind: the tenant's requests are billed to the tenant, bounded by the tenant's own quota, and governed by the tenant's agreement with Together AI. Cost blast radius, quota contention and the content-policy exposure all leave your account in one move. It also creates three new obligations that are easy to underestimate.
| What BYOK moves to the tenant | What it moves to you |
|---|---|
| The bill, in full and per tenant | Secret storage for customer-owned credentials, encrypted per tenant, with a revocation and rotation path |
| Rate-limit contention — their burst hits their ceiling | A support surface: their key, their quota, their outage, and your product is where it surfaces |
| The data-processing agreement and retention terms | Per-tenant failure handling — an expired or revoked key is now a routine, per-customer error state that needs a real UI |
The honest recommendation is that BYOK is an enterprise-tier feature, driven by procurement rather than engineering, and that shipping it does not remove the need for rungs 2 through 4. You will run both models simultaneously — pooled for self-serve, BYOK for enterprise — so the ledger needs a field recording which key paid for each row, or your per-tenant unit economics will silently include traffic you never paid for.
Abuse: When a Tenant Is Not a Customer
The last category is the one that looks like healthy growth. An endpoint that accepts arbitrary text and forwards it to Together AI is a free inference proxy for anyone who can reach it, and the traffic it attracts is indistinguishable from enthusiastic usage in every aggregate metric. Cost per active user rises, engagement looks excellent, and nobody investigates a chart that is going up.
The reliable discriminator is pacing rather than volume. Human sessions have irregular gaps — seconds to minutes, with pauses to read the output. Scripted sessions have machine-uniform intervals and no reading pause at all, and they keep going through the hours where your real users are asleep. Two cheap signals catch nearly all of it: per-tenant request intervals with a low variance, and a ratio of request volume to any product action that is not the API call itself. A tenant generating thousands of completions and saving nothing, exporting nothing and viewing nothing is not using your product.
What to do about it is a product decision, but the technical prerequisites are the same three things in this guide: authenticate before the call so anonymous traffic is impossible, meter per tenant so the cost is attributable, and hold a hard budget on free tiers so the worst case is bounded at a number you chose. For the systematic version of the cost side, see the cost attribution guide; for tenant-supplied text that tries to redirect the model rather than just consume it, see the prompt injection guide.
Where Overflow Traffic Should Go
A per-tenant budget that only ever refuses is a blunt instrument. Once admission control exists, the interesting option is routing overflow to a second provider on separate infrastructure and a separate account ceiling, so a tenant over their share degrades rather than stops.
Groq
Separate account, separate ceiling, separate invoice. Overflow routed here does not consume the Together AI headroom your other tenants are sharing.
Check Groq status →Mistral
Separate account, separate ceiling, separate invoice. Overflow routed here does not consume the Together AI headroom your other tenants are sharing.
Check Mistral status →OpenAI
Separate account, separate ceiling, separate invoice. Overflow routed here does not consume the Together AI headroom your other tenants are sharing.
Check OpenAI status →Deciding whether a destination's answer is worth the same is its own problem — see the fallback ranking guide, and note that a per-tenant overflow route needs the tenant id carried through to the second provider's ledger rows too, or the cheaper path becomes the unattributed one.
Frequently Asked Questions
Should I issue a separate Together AI API key per customer?
Only if you have first established what a key actually buys you at this provider. A key per tenant reliably buys attribution — you can tell whose traffic is whose without instrumenting anything — and it buys a fast revocation path when one tenant has to be cut off. What it usually does not buy is a quota boundary, because most providers apply rate limits at the account or organisation level regardless of how many keys that account has issued. Treat key separation as an accounting and revocation tool, and build the fairness mechanism yourself in your own process, where it can actually reject a request before it consumes shared headroom.
How do I stop one customer from consuming my whole Together AI rate limit?
Enforce a per-tenant admission decision before the outbound call, not after the provider rejects it. A token bucket per tenant, held in shared state so it holds across every process, with a refill rate assigned per plan tier and a hard concurrency cap alongside it. The concurrency cap matters as much as the rate: a single tenant issuing long-running streaming requests can occupy every connection in your pool without exceeding any per-minute rate at all. Size the sum of tenant allowances to sit meaningfully below the account ceiling, because the difference between the two is the headroom that absorbs bursts, and a system tuned to exactly 100 percent of the ceiling is a system that 429s under normal variance.
What is the right way to cap Together AI API costs per customer?
Price each request into a per-tenant ledger at write time using a dated rate table, then check the tenant's running total in the request path before the call is made. Post-hoc reconciliation against the invoice is necessary but it is a detection mechanism, not a control — by the time an invoice disagrees with your ledger, the money is spent. Run two thresholds: a soft one that degrades the tenant to a cheaper model or a smaller context and emits a warning, and a hard one that refuses. Reserve the hard refusal for free and trial tiers, where the downside of a wrong rejection is small and the upside is that an abusive signup cannot generate an unbounded bill.
Can one tenant's data leak into another tenant's Together AI responses?
Not through the provider's inference call in normal operation, but very easily through three things you built around it. A response cache keyed on prompt text alone will serve one tenant's answer to another. A retrieval index without a mandatory tenant filter will return another tenant's documents as context, and the model will use them faithfully. And a few-shot prompt assembled from recent examples across all users will paste one customer's content into another's request. All three return HTTP 200 with a plausible answer, so none of them will ever appear in an error rate. The tenant identifier belongs in the cache key, in the index filter, and in the example selector, enforced structurally rather than by convention.
Do Together AI per-model rate limits give me tenant isolation for free?
No — they give you isolation by coincidence, which is worse than none, because it removes the pressure to build the real thing. Together AI scopes limits per model, so two tenants using different models genuinely do not contend and every load test passes. The moment both land on the same model, whether by their own choice, a change to your default, or a deprecation migrating everyone onto a successor, the isolation disappears with no code change and no provider incident. Build per-tenant admission control anyway, key the bucket on tenant plus model id, and record the exact model id on every ledger row so cost and ceiling-share changes are attributable.
Related Together AI Guides
Know Whether It Is Together AI Or One Of Your Tenants
A 429 storm from your busiest customer and a real Together AI degradation are indistinguishable from inside your own traffic. API Status Check calls the provider on an independent schedule, so the first question in every multi-tenant incident already has an answer.
Start Your Free Trial →Alert Pro
14-day free trialStop checking — get alerted instantly
Next time Together AI goes down, you'll know in under 60 seconds — not when your users start complaining.
- Email alerts for Together AI + 9 more APIs
- $0 charged today — card required to start
- Cancel anytime — $9/mo after trial
🌐 Can't Access Together AI?
If Together AI is working for others but not for you, it might be an ISP or regional issue. A VPN can help bypass network-level blocks and routing problems.
Troubleshoot with a VPN
Connect from a different region to test if the issue is local to your network. Also protects your connection on public Wi-Fi.
Try NordVPN — 30-Day Money-Back GuaranteeSecure Your Together AI Account
Service outages are a common time for phishing attacks. Use a password manager to keep unique, strong passwords for every account.
Try NordPass — Free Password Manager🛠 Tools We Use & Recommend
Tested across our own infrastructure monitoring 200+ APIs daily
SEO & Site Performance Monitoring
Used by 10M+ marketers
Track your site health, uptime, search rankings, and competitor movements from one dashboard.
“We use SEMrush to track how our API status pages rank and catch site health issues early.”