> ## Documentation Index
> Fetch the complete documentation index at: https://docs.orbit.devotel.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Messaging data residency

> How the messaging-layer residency read surfaces where your SMS, MMS, and chat data is stored and processed, and how it differs from the org-level residency pin and tenant-schema isolation.

# Messaging data residency

"Where does my message data live?" is a question you can answer
programmatically. Orbit exposes a messaging-layer residency read
alongside the org-level residency pin, so a regulated buyer integrating
the messaging product reads residency where it integrates — next to
sender pools and messaging services — instead of digging through a
generic settings page. This page explains what the read reports, how it
differs from tenant-schema isolation, and how it composes with the
voice residency controls.

## Section 1 — What the messaging residency read reports

The org-level residency pin is stored and managed in the compliance
surface: one singleton configuration per organization, written through
the compliance endpoints and read everywhere else. The messaging read
**projects** that pin onto the messaging data plane and answers the
question a messaging team actually has: where are message bodies,
metadata, and logs stored and processed today?

Read your messaging residency posture:

```bash theme={null}
curl https://api.orbit.devotel.io/api/v1/messaging/data-residency \
  -H "X-API-Key: dv_live_sk_..."
```

The response carries four parts. Field values are literal examples from
an org that has enforced an EU pin; every other value the surface can
return is named below.

```json theme={null}
{
  "data": {
    "pinnedRegion": "eu",
    "enforced": true,
    "plane": {
      "plane": "messaging",
      "label": "Messaging (SMS, MMS, chat) bodies & metadata",
      "storageClass": "primary_database",
      "residencyScoped": true,
      "residentRegion": "eu",
      "processingScoped": true,
      "processingRegion": "eu",
      "note": "Stored in the primary database (European Union), matching your enforced European Union residency pin — this plane is resident in-region at rest.",
      "processingNote": "Processed by compute in the European Union region, matching your enforced residency pin."
    },
    "supportedRegions": [ /* the closed region catalog */ ],
    "storedAndProcessedInRegion": true,
    "api_region": {
      "apiRegion": "eu",
      "targetApiRegion": "eu",
      "inRegion": true,
      "targetApiEndpoint": "https://api.eu.orbit.devotel.io/api/v1",
      "targetApiEndpointLive": true
    }
  }
}
```

* **The org's residency pin** — `pinnedRegion` is the enforced region,
  or `null` when nothing is enforced; `enforced` separates a recorded
  advisory pin from an enforced one. `supportedRegions` lists the closed
  catalog (region code, label, jurisdictions, regulatory frameworks,
  per-region availability) so the messaging surface shows the choices
  without a second call to the compliance endpoint.
* **The messaging-plane status** — `plane` is the `messaging` entry of
  the org-wide data-plane matrix, same class and fields the compliance
  matrix reports. Message bodies and metadata live in the
  `primary_database` storage class, and both axes are reported: at-rest
  **storage** (`residencyScoped`, `residentRegion`) and **processing**
  (`processingScoped`, `processingRegion`), each with a plain-language
  `note` written for quoting into a register.
* **The composed verdict** — `storedAndProcessedInRegion` is `true`
  only when the pin is enforced **and** targets the region where the
  message bytes genuinely rest and are processed today. The platform
  stores and processes message data in one region (the EU; see the
  per-plane matrix in [Data residency overview](/compliance/data-residency-overview)),
  so this flag is `true` for an enforced `eu` pin and `false` for every
  other configured pin — it reports the cross-region gap rather than
  implying a guarantee.
* **The API-layer residency signal** — `api_region` is a separate
  object from the storage story above: it compares the compute region
  this API pod is actually processing in (`apiRegion`) against the
  region your enforced pin targets for REST API traffic
  (`targetApiRegion`), reports whether the two coincide (`inRegion`),
  and gives the region-pinned ingress endpoint (`targetApiEndpoint`,
  e.g. `https://api.eu.orbit.devotel.io/api/v1`) with
  `targetApiEndpointLive` stating whether that ingress is serving
  today. All of its fields beyond `apiRegion` are `null` when nothing
  is enforced — there is no target to compare against.

The pin is single-region and org-wide: one region applies to every
messaging data plane at once. There is no per-channel or per-sender
residency knob to set, and the read is exactly that — a read. Because
it projects the shared org config rather than keeping its own copy, it
answers with the same pin the compliance surface manages:

| Operation                     | Endpoint                                                   | Effect                                              |
| ----------------------------- | ---------------------------------------------------------- | --------------------------------------------------- |
| Read the pin (compliance)     | `GET /v1/compliance/data-residency`                        | Current config, region catalog, per-plane matrix    |
| Pin or update                 | `PUT /v1/compliance/data-residency`                        | Sets `region`, `enforced`, `justification`          |
| Lock / unlock the pin         | `POST /v1/compliance/data-residency/lock` and `.../unlock` | Gates region changes behind a deliberate unlock     |
| Read the messaging projection | `GET /v1/messaging/data-residency`                         | The messaging-plane view of the same pin, read-only |

Owner or admin permission is required for writes; every change lands in
your audit log.

## Section 2 — Messaging residency vs. tenant-schema isolation

Do not confuse the residency pin with tenant isolation. They answer
different questions:

* **[Tenant isolation](/concepts/tenant-isolation)** is the *hard*
  boundary. Every tenant's working data lives in its own PostgreSQL
  schema, resolved server-side from your API key on every request. That
  boundary keeps one tenant's data unreachable from another tenant; it
  applies to all tenants always, pin or no pin.
* **The residency pin** is a *within-my-tenant* choice: of the
  geographic regions the platform offers, which one should my data be
  pinned to? It is a tenant-owned control — you set it, you lock it,
  you document it. It is not a platform hard gate, and it defaults open
  until you enforce it.

Tenant isolation is a security invariant; residency is a placement
preference you opt into. Isolation is the precondition on which a
residency pin can even be meaningful — a pin only has content because
your schema is already isolated.

## Section 3 — How it composes with voice data residency

Messaging data and voice data have separate residency controls, and a
coherent posture sets both deliberately rather than assuming one covers
the other:

* **Voice data** (call recordings, voicemail, live media) follows the
  workspace voice-region pin documented in
  [Voice data residency](/compliance/voice-data-residency). It covers
  exactly those three voice data classes and nothing else.
* **Messaging data** (SMS, MMS, chat bodies and metadata) follows the
  org residency pin described above.

When you answer an audit question or a buyer questionnaire, check the
messaging read for messaging data and the voice-region page for voice
data. Pointers that conflate the two answer the question with the wrong
control. The [data residency overview](/compliance/data-residency-overview)
maps which surface answers which channel's residency question.

## Section 4 — Common setups

**Enforce the EU pin, then lock it.** The region catalog reports each
boundary as `available` or `preview`, and enforcement is only accepted
for an `available` region. The EU is the one region live today — the
same region the primary database and all platform compute already run
in — so an enforced EU pin also flips `storedAndProcessedInRegion` on
the messaging read to `true`. For a regulated EU posture:

```bash theme={null}
curl -X PUT https://api.orbit.devotel.io/api/v1/compliance/data-residency \
  -H "X-API-Key: dv_live_sk_..." \
  -H "Content-Type: application/json" \
  -d '{ "region": "eu", "enforced": true }'

curl -X POST https://api.orbit.devotel.io/api/v1/compliance/data-residency/lock \
  -H "X-API-Key: dv_live_sk_..."
```

A locked pin is refused (`409 RESIDENCY_LOCKED`) on any further region
change until you deliberately unlock it — the guard that keeps data
already written under the pin from being silently re-homed.

**Advisory pin while a region is in preview.** Every other catalogued
region (UK, US, CA, AU, BR, IN) is `preview` until its region-scoped
storage and provisioning go live. Enforcement of a preview region is
refused (`409 RESIDENCY_REGION_UNAVAILABLE`) because the platform will
not claim an at-rest guarantee it cannot keep — but an advisory pin
(`enforced: false`) to a preview region is allowed: you register where
your data needs to land, so the intent is recorded before the region
graduates.

**One org, one pin.** Residency is set per organization, and a pin
covers every messaging data plane at once — there is no per-channel
pin to keep in sync. A multi-brand operator sets each organization's
pin independently on its own compliance surface; the messaging read
then reports that organization's answer, and the audit log records who
set it.

## Section 5 — Read your posture before you certify it

Residency is one of the tenant-owned controls in your
[compliance posture](/compliance/posture-overview): Orbit provides the
surface, you own the decision and its documentation. Before you certify
a workspace's residency posture in a register or answer a questionnaire,
read the messaging surface and record what it returns:

1. **Read the messaging endpoint** and check `pinnedRegion`,
   `enforced`, and `storedAndProcessedInRegion`. A `false`
   `storedAndProcessedInRegion` means either the pin is advisory-only or
   it targets a region where message data does not rest and get
   processed today — resolve which before you certify.
2. **Check the `api_region` block** if you care about where API calls
   are processed, not only where data rests. `inRegion: false` or
   `targetApiEndpointLive: false` tells you the request path is still
   cross-region even when the at-rest story is settled.
3. **Check the lock state** if you rely on the pin as a frozen answer.
   An unlocked enforced pin can still be moved by an owner or admin;
   lock it if the register entry must not drift.
4. **Record the plain-language notes** the endpoint returns per plane —
   they are written for exactly this register entry, so quote them
   rather than paraphrasing.

<Note>
  The residency surfaces are storage-placement policy. They perform no
  outbound traffic of their own and gate no sending — configure them
  deliberately and document the reading you settle on.
</Note>

## Cross-references

* [Tenant isolation](/concepts/tenant-isolation) — the hard
  schema-per-tenant boundary the residency pin composes with.
* [Data residency overview](/compliance/data-residency-overview) — the
  map of which surface answers which channel's residency question.
* [Voice data residency](/compliance/voice-data-residency) — the
  separate pin for recordings, voicemail, and live media.
* [Compliance posture overview](/compliance/posture-overview) — where
  tenant-owned controls like this one fit in your overall posture.
