> ## 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.

# Distinctive ringing: per-caller ring rules

> Assign a ring pattern (VIP, priority, urgent) to an exact caller number or an E.164 prefix so important inbound calls sound different on your devices — how rules are stored, matched, and delivered to the phone.

A distinctive-ring rule answers one question per inbound call: *does this caller ring differently?* You assign a ring pattern — VIP, priority, urgent, internal, external — to an exact caller number or a number prefix, and any matching inbound call arrives on your devices with its own ring cadence instead of the default. A support lead hears the on-call escalation line before they reach for the handset; a VIP customer's call is distinguishable from cold traffic by sound alone.

Everything on this page is per-user and self-service: your rules are yours, they take effect only on calls that ring *you*, and no admin or supervisor right is required. Distinctive ringing only changes how an inbound call is presented on your own registered devices — it never originates a call leg and never touches an outbound carrier.

**Base path:** `/api/v1/me/ring-rules`

**Authentication:** Clerk session (`Authorization: Bearer <token>`) or API key (`X-API-Key`). The `me` surface always acts on the signed-in user; there is no way to read or write another user's rules.

***

## 1. What a rule is

One rule is three fields plus an optional label:

| Field         | Values                                                          | Meaning                                                                                                                                                                                     |
| ------------- | --------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `match_kind`  | `pstn` or `prefix`                                              | Whether `match_value` is one exact caller number or a number prefix.                                                                                                                        |
| `match_value` | E.164 string with leading `+`                                   | The exact caller number (`pstn`, e.g. `+14155550100`) or a prefix that the caller's number starts with (`prefix`, e.g. `+1800` for a toll-free range or `+4420` for a London office block). |
| `pattern`     | `standard`, `priority`, `urgent`, `vip`, `internal`, `external` | The ring treatment for matching calls. `standard` is the platform-default ring; the rest each carry their own distinct treatment.                                                           |
| `label`       | optional string, up to 64 characters                            | Display text for the picker (e.g. "CEO direct"). Never affects matching.                                                                                                                    |

Use a `pstn` rule when one specific number matters (the CEO's mobile, the on-call escalation line). Use a `prefix` rule when a whole range shares a treatment (every caller from the `+1800` toll-free block rings as `priority`). The `standard` pattern exists so you can *exempt* one number from a broader prefix rule — assigning `standard` to an exact number means "ring this caller normally, even though a prefix rule would have matched."

***

## 2. How the rule reaches the phone

Distinctive ringing travels on the voice plane as a SIP `Alert-Info` header on the inbound ringing leg. The pattern catalog — returned by `GET /api/v1/me/ring-rules` alongside your rules — maps each pattern id to the `Alert-Info` value your device receives:

| Pattern    | Label          | `Alert-Info` value                           |
| ---------- | -------------- | -------------------------------------------- |
| `standard` | Standard ring  | *(no header — the device rings its default)* |
| `priority` | Priority alert | `info=alert-priority`                        |
| `urgent`   | Urgent alert   | `info=alert-urgent`                          |
| `vip`      | VIP ring       | `info=alert-vip`                             |
| `internal` | Internal ring  | `info=alert-internal`                        |
| `external` | External ring  | `info=alert-external`                        |

The header uses the same bare `info=<token>` convention the platform already ships for paging auto-answer, so the value is provider-neutral. A SIP deskphone maps the token to a locally configured ring cadence; the browser softphone plays the corresponding ring tone itself. The catalog entry's `priority` flag is advisory metadata for the UI (badging, sort order) — the audible difference is carried entirely by the `Alert-Info` value.

One practical consequence: because `standard` maps to *no header*, a `standard` rule on an exact number suppresses a broader prefix rule cleanly — the phone does its everyday ring and nothing special is stamped on the leg.

***

## 3. Storage semantics: one array, replaced as a whole

Your rules persist on your user record next to your other signed-in preferences — **not** in browser storage. They survive clearing the browser, switching laptops, and signing in from a new device; anywhere you are authenticated, your ring rules follow.

The write model is deliberately blunt: `PUT /api/v1/me/ring-rules` **replaces your entire rules array in one call**. There is no per-rule POST/PATCH/DELETE. The list is small enough that the whole-array write stays simple, and one atomic replace avoids read-modify-write races if you edit from two tabs at once. This is the opposite trade-off from favorites (per-item writes), so don't assume one from the other.

```bash cURL theme={null}
# Read back rules + catalog
curl "https://api.orbit.devotel.io/api/v1/me/ring-rules" \
  -H "X-API-Key: dv_live_sk_your_key_here"

# Replace the whole array — anything not in this list stops existing
curl -X PUT "https://api.orbit.devotel.io/api/v1/me/ring-rules" \
  -H "X-API-Key: dv_live_sk_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "rules": [
      { "match_kind": "pstn", "match_value": "+14155550100", "pattern": "vip", "label": "CEO direct" },
      { "match_kind": "prefix", "match_value": "+1800", "pattern": "priority" },
      { "match_kind": "pstn", "match_value": "+18005559999", "pattern": "standard", "label": "Pharmacy line — ring normally" }
    ]
  }'
```

Send `"rules": []` to clear all rules. To *edit* one rule, PUT the full list with your change; to *delete* one, PUT the list without it.

Every rule is validated before anything is written — a bad entry rejects the whole call and changes nothing:

* **400 with `details` per issue** — a malformed request shape (unknown field, wrong type, more than 50 rules). The `details` array names the offending field.
* **422 with `details.offendingRule`** — a well-shaped body whose rule content fails validation: an E.164 `pstn` value without the leading `+`, a `prefix` value that isn't a leading-`+` E.164 prefix, an unknown pattern id, or a label over 64 characters. The echoed `offendingRule` is the first failing entry.

Duplicate rules for the same `(match_kind, match_value)` target are deduplicated on write, keeping the first occurrence — the stored list never holds two rules for the same target, so matching (next section) never faces an ambiguous duplicate.

***

## 4. Matching and limits

When an inbound call rings you, the caller's number is normalized (SIP URI wrappers stripped, digits and leading `+` preserved; anonymous or withheld callers never match) and resolved against your rules with a fixed precedence:

1. **Exact beats prefix.** A `pstn` rule for the caller's exact number always wins over any `prefix` rule — this is what makes the `standard`-exemption pattern work.
2. **Longest prefix wins.** Among competing prefix rules, the most specific (longest) match applies — a `+18005` rule beats a `+1800` rule for `+18005551234`.
3. **First configured wins ties.** Two equally long prefixes can overlap; the earlier rule in your array decides.

Limits, enforced on every PUT:

| Limit                | Value                                           |
| -------------------- | ----------------------------------------------- |
| Max rules per user   | 50                                              |
| `match_value` length | 1–32 characters                                 |
| `label` length       | up to 64 characters                             |
| `pstn` shape         | leading `+`, first digit 1–9, 7–15 digits total |
| `prefix` shape       | leading `+`, first digit 1–9, 1–15 digits total |

Fifty prioritized numbers is well beyond any realistic VIP list; if you approach the cap, fold whole ranges into a single `prefix` rule.

***

## 5. Interplay with your other calling preferences

Ring rules decide *how* a matching call rings; the pages below decide *where* it rings and what the phone declares itself to be. They compose independently — a `vip` cadence applies identically whichever destination answers.

* **[Configure your voice preferences](/guides/me-voice-preferences)** — the ring-mode ladder (softphone only, forward all, simultaneous, sequential, forward-after-timeout). A simultaneous ladder rings your browser softphone and your mobile; the distinctive pattern is stamped on every ringing destination.
* **[Browser softphone calling](/guides/voice-softphone-browser-calling)** — the browser profile plays the pattern's ring tone in-browser rather than mapping the SIP header.
* **[Extensions and desk phones](/guides/extensions-and-desk-phones)** — provision a physical phone under your extension and it maps `info=alert-vip`, `info=alert-urgent`, etc., to locally configured cadences; check the phone's own ringtone assignment for the exact effect.
* **[Inbound number routing](/guides/inbound-number-routing)** — ring rules apply wherever the call arrives (direct extension, ring group, queue overflow to you), because the resolution happens on *your* rules at ring time.

***

## 6. Where the picker lives

The dashboard picker for these rules sits on **Me → Voice preferences** (`/me/voice-preferences`) alongside the ring-mode editors — the same page your agent callers already visit for call forwarding. The picker reads the catalog from `GET /api/v1/me/ring-rules`, renders one row per pattern with its label, and saves the whole list back with the full-array PUT. There is no org-wide ring-rules page; the feature is intentionally scoped to "my inbound calls, my ring."

<Note>
  Agents who mostly use the web dashboard can treat the API as unnecessary — the picker is the same GET/PUT pair with a friendlier form. The API matters when a softphone integration or an internal tool wants to provision rules for users programmatically within your tenant.
</Note>

***

## Related references

* [Configure your voice preferences](/guides/me-voice-preferences)
* [Browser softphone calling](/guides/voice-softphone-browser-calling)
* [Extensions and desk phones](/guides/extensions-and-desk-phones)
* [Inbound number routing](/guides/inbound-number-routing)
* [Account API reference: `GET|PUT /api/v1/me/ring-rules`](/api-reference/endpoints/account)
