Keep calls in your regions¶
The concept behind models and routing is explained in Models and routing.
A policy can decide in which regions Core may work on your key's behalf. Put a list of regions in
policy.settings.regions_allow and Core holds every destination of a call to that list: the model
that answers, but also the embedding model, the tools, the services behind a knowledge connector and
the computers. A destination outside the list is refused, unless your policy names it as a
residency exception.
Without a list (regions_allow is null, the default), nothing on this page applies.
Restrict regions¶
The list sits in the settings of the policy document of a key, of your organisation, or of both:
{
"settings": {
"regions_allow": ["eu"]
}
}
A region is spelled eu, us, global, in-cluster (your deployment's own infrastructure) or a
two-letter country code such as nl. Regions nest: in-cluster and every EU member state lie inside
eu, and everything lies inside global. A destination in nl therefore satisfies a list naming
eu; a destination in us or global does not. An empty list is refused.
In the console these fields are under Where data may go, on the Settings card of a key's
policy and of the organisation's (Keys). A key with management
sets them over the API:
PATCH /keys/{key_id} with policy for a key, PUT /organisation/policy for the organisation
(Manage organisations through the API). Both replace the whole document, so
read it first with GET /keys/{key_id} or GET /organisation/policy and send it back complete,
rules included: a setting you leave out falls back to its default, and a document sent without
rules gets the default rules, which permit no host for a tool and no memory write. To avoid
overwriting a change someone saved between your read and your write, send the version you read in
If-Match (Hand out, rotate and withdraw keys).
Every document counts. When your key, your organisation and the organisations above it restrict regions, a destination has to satisfy each of them. A key can therefore only narrow its organisation's policy, never widen it, and an organisation only narrows what the organisations above it admit (The organisations above count too).
What it applies to¶
| Destination | Where its region comes from | What happens when it is outside the list |
|---|---|---|
| The model that answers | the model's region and country, in GET /models |
the turn gets 403 (Hosting refusals) |
| The embedding model (knowledge, memory, skills) | the same | the turn runs without searching your knowledge; a route that embeds, such as POST /memory, answers 403 |
| The model that summarises a thread | the same | the thread goes to the model verbatim, without a summary |
| A knowledge pipeline's model steps | the same | the step fails; a search tool answers Denied by policy. |
| An image model | the same | the tool answers Denied by policy. |
| An audio model | the same | POST /audio/transcriptions and a request with input_audio answer 403; the transcription tool answers Denied by policy. (Transcribe audio). A recording is never pseudonymised, so this is what decides where it goes |
| The host of an API connector or MCP server | the source's region, or policy.settings.host_regions (Allowed destinations) |
the tool answers Denied by policy. |
| A callback URL or webhook | policy.settings.host_regions |
creating it answers 403; a delivery is dropped |
builtin__web_fetch, builtin__web_search |
the services run in the United States | the tool answers Denied by policy. (Web fetch and search) |
A website connector, crawled through Firecrawl |
the United States | sync and test fail with region_denied (Knowledge) |
The llama_parse step, through LlamaCloud |
the EU by default, or the region your operator set | the source fails with region_denied |
| A computer | the region your operator set for your organisation's computers | the tool answers Denied by policy. (Computers through the API) |
The embedding model is also held to your rules over models, with or without a region list: a policy that narrows models must permit the embedding model too (Knowledge).
A destination whose region nobody declared is refused: Core does not assume it is in the right
place. Every refusal is in your audit trail as a policy.decision with
decision: denied.
Residency exceptions¶
Sometimes one destination outside your regions has to be reachable: a US search service under an EU
policy, or one model that only runs elsewhere. Adding us to your list would open every US
destination, models included. Name that one destination in policy.settings.region_exceptions
instead:
{
"settings": {
"regions_allow": ["eu"],
"region_exceptions": ["builtin:web_search", "host:api.tickets.example.com"]
}
}
Each entry names exactly one destination, in one of these forms:
| Form | What it names |
|---|---|
model:<model id> |
one model, its id exactly as GET /models spells it; no wildcards |
host:<host> |
one host, or *. plus a domain of at least two labels (host:*.example.com, not host:*.com): the host of an API connector or MCP server, a token endpoint, a callback or a webhook |
builtin:web_fetch, builtin:web_search |
the services behind the web tools |
builtin:computer |
your organisation's computers |
vendor:firecrawl |
a website connector's crawl |
vendor:llamacloud |
the llama_parse step |
Any other form is a 422. An exception counts only in a document that restricts regions itself.
Every document has to allow the destination. Each document that restricts regions is asked on
its own: it allows a destination when its own regions_allow admits the place or its own
region_exceptions names the destination. When your organisation holds itself to eu, an
exception on your key helps only if the organisation's policy names the same destination too. When
your organisation already admits us, it does not have to repeat your key's exception for a US
model. A host: wildcard covers the hosts beneath it, so host:*.firecrawl.dev on the organisation
and host:api.firecrawl.dev on the key together let api.firecrawl.dev through. A service counts
as named both under its own name and under the host it dials. The same holds for every
organisation above yours that restricts regions
(The organisations above count too).
Wherever the destination runs, even when nobody knows. An exception names a destination, not a
place. So it also covers a destination whose region nobody declared, such as an MCP server without a
region. Because no region admits an unknown place, every document that restricts regions then has
to name the destination itself.
An exception lifts nothing else. The rules of your policy, for models, tools, hosts and
people alike (Write your first rule), the
hosts your organisation allows, the hosts your deployment blocks and a turn's own hosting.region
all still apply.
When a request asks for hosting.region: "eu", a model outside the EU is refused even if the policy
has an exception for it: whoever sent the request asked for that place.
Every use is recorded. A call an exception let through is in the audit trail as a
policy.decision with decision: allowed and reason: allowed by residency exception; refs names
the exception that allowed it.
Hold vendors to places¶
A region says where a call is processed, not who processes it. A model served in the EU by a
company whose parent sits in the United States answers to both. policy.settings.vendors_allow
holds the company behind each destination to places, and a model to open weights:
{
"settings": {
"vendors_allow": {
"established_in": ["eu"],
"parent_in": ["eu"],
"open_weights": true
}
}
}
established_inlists where the company serving a destination may be established,parent_inwhere its ultimate parent may be, in the same spelling asregions_allow. Leave either out to not ask about it.open_weights: trueadmits only models whose weights are published, so another host could serve them.- A fact nobody stated counts as
global, so a requirement namingeurefuses it until someone states it. No residency exception lifts a refusal here.
Your operator states who runs each model's provider and whether each model's weights are open;
GET /models shows both as vendor and open_weights. You state it yourself for what you
register: vendor on an API connector, an MCP server or an event webhook, and callback_vendor
beside a run's callback_url, each {"established_in": "nl", "parent_in": "nl"}; a company with
no parent gives its own place. GET /key answers vendors_allow with every requirement your key
is decided under. Every document counts, as for regions, and the console has no field for this
setting yet: it is written over the API, and a save in the console keeps it. A refused model
answers 403 with The model is not run by a company this key allows. or The model's weights
are not open, as this key requires.
The organisations above count too¶
When your organisation sits under another, the three lists under policy.settings of every
organisation above it (regions_allow, region_exceptions and host_regions) are weighed beside
your organisation's and your key's. You cannot read those documents unless you administer those
organisations too. This is what they do to your calls:
- The regions have to meet. A destination has to lie inside the
regions_allowof every document that has one. An organisation above that holds itself toeukeeps every organisation below it ineu, whatever their own lists say. - Every restricting document must admit the destination or name it. An exception in your policy lets a destination through only when each organisation above that restricts regions admits the place itself or names the same destination among its own exceptions. When an organisation above does neither, ask its administrator to add the exception.
- A host placed above is placed for you. When an organisation above declares in its
host_regionswhere a host is served, you need not declare it again. When your document and a document above place the same host in two different regions, the host counts as placed nowhere and is refused as unknown. Remove your own declaration, or ask the administrator above which region theirs names.
See where your calls may go¶
GET /key answers in residency what every document your key is decided under allows together:
your key's, your organisation's and those of the organisations above it.
{
"residency": {
"regions_allow": ["eu"],
"region_exceptions": [
{ "exception": "builtin:web_search", "where": null }
]
}
}
regions_allowis where all the lists meet. Empty means they have nothing in common, and then no destination is reachable at all.region_exceptionsnames every exception of your key and your organisation that your calls are decided with, withwhere:nullwhen the destination is reachable wherever it runs, because every restricting document names it. When a restricting document does not name it,wherelists the places that document admits itself. When your organisation holds itself toeuand names a model as an exception, while your key admits onlyus, that model is listed withwhere: ["us"], althoughregions_allowis then empty. An exception that adds nothing toregions_allowis left out. The exceptions of an organisation above are weighed and are not listed.residencyisnullwhen no document restricts regions.
The model listings weigh exceptions too: a model only an exception admits is listed in
GET /models and is allowed in ?kind=image, ?kind=audio and ?kind=embedding (Models your key reaches
without naming them).
Work started in the console¶
What someone does in the console for your organisation follows the organisation's region choices: a
search or Try it on a search tool, a pipeline test, writing a skill, a connector test, and
ingesting a source or connector someone set up in the console. So does the work an installed
publication does for your organisation. For that work, the regions_allow, region_exceptions and
host_regions of the organisation's policy count, and the same three
lists of every organisation above it. Of the rules, only those about destinations count, the
organisation's own (Allowed hosts) and those of the
organisations above. The other rules and settings are for keys, and a person working in the console
is not a key. When neither the organisation nor one above it restricts regions, that work is not
restricted by region.
An action that embeds text with a model outside those regions is refused with The embedding model
is not hosted in a region this organisation allows.