Regions and data residency
Ringside runs inference in the US by default with no residency guarantee. To pin where a call physically executes, append an @<region> suffix to a fc: model ref. The suffix picks both a region (EU or US) and a route (OpenAI in-region, or Claude via AWS Bedrock or Google Vertex). Residency is the only thing it changes. The billing model, list price and model behaviour are identical to the un-suffixed ref, and region-pinned responses are cached in their own keyspace so an EU answer is never served to a US-pinned request.
Most callers never touch this page. A bare fc:openai/gpt-4o-mini or fc:anthropic/claude-sonnet-4.6 routes through the default fightclub adapter, which is US/global and makes no promise about which datacentre handles the bytes. That is fine for most workloads. When you have a GDPR commitment, a customer contract that names a jurisdiction or an internal policy that says EU user data stays in the EU, you need the request to run in a known region. That is what the @<region> suffix does.
The suffix is opt-in and it changes nothing about how you bill or read a response. It pins the upstream the call dispatches to. Everything downstream (the catalog price, the capability lookup, the response shape) stays keyed to the canonical model, so turning residency on for a route does not move you onto a different price or a different model.
A fc: ref names a model. The @<region> suffix names where that model runs and through which cloud. The two are orthogonal. fc:openai/gpt-4o-mini and fc:openai/gpt-4o-mini@eu are the same model at the same price, served from different regions.
The region suffixes
There are six suffixes across two regions and three routes. The OpenAI suffixes (@us, @eu) hit OpenAI directly in-region. The Bedrock and Vertex suffixes serve Anthropic Claude through a hyperscaler region instead of through Anthropic directly, which is the usual path to a contractual EU-residency guarantee for Claude.
| Suffix | Provider / route | Region | Where it runs |
|---|---|---|---|
@us | OpenAI direct | US | api.openai.com |
@eu | OpenAI direct | EU | eu.api.openai.com |
@us-bedrock | Claude via AWS Bedrock | US | us-east-1 |
@eu-bedrock | Claude via AWS Bedrock | EU | eu-west-1 |
@us-vertex | Claude via Google Vertex | US | us-east5 |
@eu-vertex | Claude via Google Vertex | EU | europe-west1 |
The OpenAI suffixes attach to openai/* models only. The Bedrock and Vertex suffixes attach to Claude models that are mapped to a cloud-native id (the Opus, Sonnet and Haiku families). A suffix on a base that does not support that route is rejected. More on that in the errors section below.
The rules
- Suffix attaches to fc: refs only
- Residency pins a concrete model, so the suffix is valid only on a fully-pinned
fc:ref. It does not attach tomatch:,slot:ordyn:refs, and the model id inside anfc:ref carries the suffix on the end:fc:openai/gpt-4o-mini@eu. - Same catalog price
- Cost is computed against the canonical model id (the part before the
@) through the normal catalog. A region-pinned call bills at the same list price as the un-suffixed ref. Residency changes where the call runs, not what it costs. - Identical model behaviour
- You are calling the same model, so capabilities (context window, vision, tool calling), defaults and output shape are unchanged.
fc:openai/gpt-4o-mini@eubehaves exactly likefc:openai/gpt-4o-mini. - Region-pinned responses cache separately
- Ringside's response cache keys on the resolved model id including the region label, so a cached EU answer is never returned to a US-pinned request (or the reverse), even for a byte-identical prompt. The two regions occupy separate cache keyspaces.
- Unknown or unsupported region is a 400
- An unrecognised suffix, or a known suffix on a base that does not support that route, fails fast with a 400 before any upstream is called. No spend, no partial result.
Because the suffix attaches to fc: refs only, you cannot put residency on a match:/slot:/dyn: selector or on a model array cascade entry that resolves through those. Pin the exact model with fc: first, then add the suffix.
Worked example
Pin a chat call to EU residency by routing Claude through Bedrock in eu-west-1. The request is an ordinary chat completion; the only change from the un-suffixed call is the @eu-bedrock on the model id.
curl https://api.fightclub.pro/v1/chat/completions \
-H "Authorization: Bearer $FC_API_KEY" \
-H "FC-Customer: cus_42" \
-H "Content-Type: application/json" \
-d '{
"model": "fc:anthropic/claude-sonnet-4.6@eu-bedrock",
"messages": [{"role":"user","content":"Summarise this support ticket."}]
}'The response body is the standard chat completion shape. Cost lands on cus_42 exactly as it would without the suffix; read X-Ringside-Wallet-Deducted for the exact charge. Headers like X-Request-Id, X-Ringside-Wallet-Balance and FC-Cache-Status work the same way they do on any chat call.
Picking a region for GDPR and residency
The decision is jurisdiction first, then provider. If your obligation is to keep EU personal data inside the EU, pick the @eu family. For OpenAI models that is @eu. For Claude you have two EU routes, @eu-bedrock (AWS eu-west-1) and @eu-vertex (GCP europe-west1); pick whichever cloud your data-processing agreements and DPAs already cover.
- ·OpenAI model, EU residency:
fc:openai/gpt-4o-mini@eu. - ·Claude on AWS, EU residency:
fc:anthropic/claude-sonnet-4.6@eu-bedrock. - ·Claude on Google Cloud, EU residency:
fc:anthropic/claude-opus-4.8@eu-vertex. - ·US residency, same patterns:
@us,@us-bedrock,@us-vertex.
The suffix guarantees Ringside dispatches the call to the named cloud region. Your residency posture still depends on your contracts with that cloud and with the model provider (DPAs, sub-processor lists, zero-retention terms). Pin the region, and keep the paperwork that matches it.
Caching behaviour
When the response cache is on (via the FC-Cache request headers or cache_control), the cache key includes the region label. So fc:openai/gpt-4o-mini@eu and fc:openai/gpt-4o-mini@us with an identical prompt produce two separate cache entries. This is deliberate. A response generated in the EU must never be served to a request that asked for US residency, and a hit on the wrong region would break exactly the guarantee you turned the suffix on for.
A practical consequence: if you address the same model through two different regions you will not share cache hits between them. Stick to one region per corpus or workload where you want the cache to actually help.
Errors
Region resolution happens before any upstream call, so a bad suffix costs you nothing. Both failures below surface as a 400 with an invalid_request_error type. Always branch on the code, never the human message.
| Status | code | When |
|---|---|---|
| 400 | invalid_model_ref | The @<suffix> is not one of the six known tags (a typo like @europe or @eu-azure). The message lists the supported suffixes. |
| 400 | unsupported_provider | A known suffix on a base that does not support that route: an @eu/@us (OpenAI direct) suffix on a non-openai/* model, or an @*-bedrock/@*-vertex suffix on a Claude model that has no cloud-native id mapped. |
{
"error": {
"type": "invalid_request_error",
"code": "unsupported_provider",
"message": "Region suffix '@eu' (OpenAI direct) is only valid for openai/* models, not 'anthropic/claude-sonnet-4.6'. For Claude use @eu-bedrock or @eu-vertex."
}
}The two error codes map to two fixes. invalid_model_ref means the suffix string is wrong (check the table at the top). unsupported_provider means the suffix is real but does not apply to that model (a Claude model needs @*-bedrock or @*-vertex, not @eu/@us).
What does not change
- ·Authentication: the same
Authorization: Bearer ko_...developer key orAuthorization: Client <jwt>client token. - ·Billing and metering: the canonical model is the billing model;
X-Ringside-Wallet-Deductedreports the charge,FC-Customerattributes it. - ·Request and response wire shape: identical to the un-suffixed chat call, including streaming and tool calls.
- ·Limits: the standard chat limits apply (messages serialise to 100,000 bytes; image input 20 MB, max 2 per message).
Region-pinned routes serve a single concrete model, so they are not combinable with a model array cost cascade in the way a normal fc: ref is across providers. Add the suffix to a single pinned model and call it directly when residency is the requirement.
Default behaviour
No suffix means no residency guarantee. The call routes through the default fightclub adapter (US/global). Existing traffic is untouched by this feature; you only opt in by adding a suffix, and you can do it per call. There is no account-wide region setting to flip. If a particular call must stay in a region, pin it on that call.