Routing
Processing regions: Switzerland, the EU, the US, or no preference
How much of your data leaves, which model catalogue is eligible, and which jurisdiction the work may stand in. They are three separate axes, they are resolved in one place each, and the answer is on the response — not in a support ticket.
Three axes
Orthogonal, not a single dial.
Conflating these is the classic mistake: “full-data” does not mean “PHI”, and “PHI” does not mean “EU”. Each axis has its own resolver, its own default, and its own failure direction.
First axis — how much data leaves
Second axis — which catalogue is eligible
Third axis — where compute may stand
- Standard is the default
- PHI locked behind the BAA
- Pinned ids, never a silent auto-route
- +20% follows the actual routing
- Host allowlist fails closed
The decision
One resolver, and it defaults to the cheaper answer.
Until 2026-09-01 an unconfigured workspace defaulted to PHI. That was reversed: standard is now what you get, and PHI is an explicit opt-in alongside accepting the BAA. Every fail-soft path resolves to standard too — an unreadable settings row must never silently upgrade unknown traffic into a surcharge and an agreement gate.
One resolver
resolveRunPhi(tenantId, requested) → lib/agreements.ts
- 1phi_mode in the request body — Chat’s Standard / PHI · enterprise switch, or your own API call.
- 2Otherwise tenants.phi_mode, the workspace default.
- 3Otherwise standard — and that is also where an unreadable settings row lands.
- 4An explicit PHI ask with no BAA acceptance on file is 403 agreement_required, with a pointer to the settings page. Never a silent downgrade.
Standard
the default- Headers
- X-Region only. No X-PHI is sent.
- Model
- A pinned id from our own three-rung ladder, resolved by modelFor().
- Region
- US for the ladder call; the workspace pin still governs sandbox placement.
- Price
- No uplift.
PHI · enterprise
explicit opt-in- Headers
- X-PHI: true plus X-Region set to your workspace pin.
- Model
- Named by phi-cloud from the residency-locked PHI catalogue. We name nothing.
- Region
- Your pin. The host must also be on the BAA allowlist or the call is refused.
- Price
- +20% on the whole charge.
What goes on the wire
Two header sets, one endpoint.
Both branches call the same phi-cloud endpoint. The difference is two headers and whether we name a model at all. A standard call carries a concrete pinned id and the region that serves it; a PHI call carries the data class and the jurisdiction and lets the gateway that holds the BAA make the pick.
The allowlist sits underneath both: MAPR_PHI_ALLOWED_HOSTS names the hostnames permitted to receive full-data traffic, and in production an unset allowlist refuses rather than permits. See the fail-closed gates.
# Standard routing — the default for an unconfigured workspace.
POST /v1/chat/completions → phi-cloud
X-Region: US # the region that SERVES the pinned id
model: inception-mercury-2 # low rung, resolved by modelFor()
# no X-PHI header at all
# PHI · enterprise routing — only after the BAA is accepted in-app.
POST /v1/chat/completions → phi-cloud
X-PHI: true # forces the PHI-eligible catalogue
X-Region: CH # the workspace pin
model: auto # phi-cloud picks, in-regionThe general ladder
Three rungs for traffic that is not regulated.
Non-PHI work runs on models we pin by id. The rungs are a capability and latency ladder, not a price ladder — and the ids are pinned precisely so nobody, including us, can quietly re-route them.
| Rung | Model | Override |
|---|---|---|
| lowThe default. Most turns, and every call that names no tier. | inception-mercury-2 | MAPR_GENERAL_MODEL_LOW |
| midOne real piece of work. | zai-glm-5-3-flash | MAPR_GENERAL_MODEL_MID |
| highThe rung a tier:"quality" codegen or critic turn is promoted to. | zai-glm-5-3 | MAPR_GENERAL_MODEL_HIGH |
The ids are pinned on purpose
The ladder is not price-ordered
PHI is deliberately not on it
Heavy turns are promoted
What routing costs
The uplift follows the routing a run actually got.
Not the routing it asked for, and not the policy the workspace has set. If a run was downgraded to standard for any reason, it is billed as standard and flagged as downgraded — that is a compliance rule wearing a pricing rule's clothes.
| What is charged | Rate |
|---|---|
| Every map, deterministic or notCharged even when the cascade resolves every column without touching a model, and on a layout-fingerprint cache hit that uses no AI at all. | Flat per-map fee (~$0.001) |
| AI cleanup, convert, reshapeThe AI tokens actually consumed, on top of the flat fee. × 0.5 on the token component when you bring your own LLM key. | Flat fee + provider cost × 2 |
| Columns settled by our own matching modelCascade layer 3½ bills like a model call: about $0.0000 per column it resolves (× 0.5 with your own key) — roughly a thousandth of what the same column costs on the LLM. | Flat fee + its cost × 2 |
| Macro authoringA delegated VBA edit draws the same flat fee a map does, and nothing else: the settle call passes zero prompt tokens, zero completion tokens and zero provider cost, so the delegated turn’s own tokens are not metered back to you. Reading a workbook’s macros — modules, entry points, risky-call signals — is deterministic and free. | The flat per-map fee |
| PHI · enterprise routingFlat fee included. Applied only when the run actually routed as PHI — see the rule below. | +20% on the whole charge |
# The kill switch that makes this rule necessary.
MAPR_RESHAPE_DISABLE_PHI=1
# It strips X-PHI from the sandbox execution call. The run therefore
# did NOT go through the PHI path, so effectiveRunPhi() returns false:
charge standard rate, no 20% uplift
audit payload phi_downgraded: true
response a user-visible warning saying so
# Charging a BAA premium for a run that bypassed the BAA gate is a
# claim we cannot make — /pricing sells the uplift as "routed
# in-region under a BAA", and this run was not.Why this matters
A premium you cannot justify is a claim you should not make.
The 20% is sold as “routed in-region under a BAA”. If an operator kill-switch strips the PHI header from a sandbox execution, that particular sentence stops being true for that particular run — so the run is charged at the standard rate, phi_downgraded lands in the audit payload, and you see a warning in the result.
It would have been easier to bill the requested policy. It would also have been an invoice line describing something that did not happen. See the full pricing model and the BAA gate.