Skip to content

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_in lists where the company serving a destination may be established, parent_in where its ultimate parent may be, in the same spelling as regions_allow. Leave either out to not ask about it.
  • open_weights: true admits only models whose weights are published, so another host could serve them.
  • A fact nobody stated counts as global, so a requirement naming eu refuses 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_allow of every document that has one. An organisation above that holds itself to eu keeps every organisation below it in eu, 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_regions where 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_allow is where all the lists meet. Empty means they have nothing in common, and then no destination is reachable at all.
  • region_exceptions names every exception of your key and your organisation that your calls are decided with, with where: null when the destination is reachable wherever it runs, because every restricting document names it. When a restricting document does not name it, where lists the places that document admits itself. When your organisation holds itself to eu and names a model as an exception, while your key admits only us, that model is listed with where: ["us"], although regions_allow is then empty. An exception that adds nothing to regions_allow is left out. The exceptions of an organisation above are weighed and are not listed.
  • residency is null when 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.