Skip to main content

Branded Calling (Rich Call Data)

Rich Call Data (RCD) is the STIR/SHAKEN extension that lets a verified brand render on the recipient’s incoming-call screen: your display name, a square logo, and a short reason-for-call line appear in place of the bare number. Branded calling is the configuration surface for it — which brand assets you send, how broadly they render, and how much of your traffic you hold out to measure the answer-rate lift honestly.

RCD vs. CNAM

CNAM and RCD solve different parts of caller presentation: CNAM strings are anything a handset pulls from its database dip; RCD is the brand carried cryptographically inside the signed call. Both live under the caller-identity umbrella — CNAM for the fallback label, RCD for the verified one. See CNAM & Caller ID.

STIR/SHAKEN A-attestation — the prerequisite

RCD rides inside the signed PASSporT, so it exists only where full attestation exists. The from-number must present A-attestation — the platform signs an A-level call only when the number is an active number your organization owns through the platform. The fallback ladder matters for outbound posture:
  • A-attestation. Eligible for RCD. The verified brand can render.
  • B (partial) or C (gateway) attestation. RCD is never carried; the recipient sees the attestation label and any CNAM name on file. A caller ID you don’t own (an external caller-ID string, or a number not yet ported/purchased into the platform) falls to B or C.
Treat attestation as the gate: a branded-calling configuration on an owned, A-attested number is a live experiment; the same configuration off a non-owned caller ID pays nothing. See STIR/SHAKEN attestation for the controls that decide the level.

Prerequisites

Before RCD can render anywhere, four things must hold:
  1. STIR/SHAKEN A-attestation on the caller number, as above. Without it, the RCD payload is suppressed for every call.
  2. A public brand logo over HTTPS. The URL is what the handset fetches — it must be publicly reachable without authentication, served over TLS, and on a stable URL (no expiring signed links). The write-time validator also enforces this (safeHttpsUrl rejects http and loopback/private hosts with SSRF guard).
  3. Owner or admin access. Branded calling is set on the organization; only owner/admin roles can save it.
  4. Per-carrier brand registration. RCD renders only on carriers where your brand registration completed. Registration is an operator-managed side-band with the Devotel branded-calling team — the platform tracks a registered_with_carriers list for you, but a tenant cannot self-attest it. Until the list is populated the headers still go out; downstream carriers silently drop the payload.

Configuration fields

Set the brand assets in Settings → Voice → Branded calling, or with the API:
Fields are validated when you save — the name length, reason length, and a full safeHttpsUrl check on logo_url are all enforced at write time, so an out-of-spec value returns a 422 rather than store and fail downstream. The save response echoes the persisted record. Two fields behave like patches, not full replaces:
  • Omitted holdout_pct preserves the running experiment. A settings form that only edits brand assets must not silently reset a running branded-vs-unbranded measurement. An explicit number updates it; no prior value falls back to 0 (off).
  • registered_with_carriers is read-only to the tenant. Any sent value is ignored, and the stored list from the last completed registration is preserved server-side.
Saving changed brand assets (a new name, logo, or reason-for-call) resets the brand-verification state to unverified, so the revised brand goes back through review before it is trusted on the handset. Toggling enabled alone or adjusting holdout_pct does not reset the verdict — only the rendered assets trigger re-review.

Measuring the lift with the hold-out experiment

Answer-rate measurement is the whole point of branded calling, and the only honest read is a randomized control. The holdout_pct field withholds the RCD payload from that percentage of otherwise-branded calls — the two cohorts share the same traffic, time window, and dialing behaviour; only the brand differs. The dial path stamps each eligible call’s cohort (branded vs holdout) onto the call record; the readout GET /numbers/:id/branded-calling-cohort reports the branded-over-unbranded uplift split out of actual call logs. Run the hold-out long enough for the two cohorts to reach size, and lift reads as a real effect rather than a before/after time-series confounded by campaign mix. Withholding a verified brand does cost answer rate, so the platform caps the hold-out at 50% of eligible traffic — and a non-finite stored value fails safe toward branding.

Signing vs. signalling — where the certificate lives

Branded calling is a signalling surface, not a signing one. The platform never signs the STIR/SHAKEN PASSporT itself — signing happens on the Devotel wholesale softswitch, the carrier of record, which holds the STIR/SHAKEN signing certificate and owns the per-carrier branded-calling registrations. At dial time the platform resolves your saved branded-calling configuration and the caller-ID number’s per-number profile (a set profile overrides the organization default for that number), and signals the resulting brand assets to the softswitch on the outbound leg alongside the attestation level. Headers move on the existing Devotel outbound path — origination and routing are never changed, and a signalling failure never blocks the call. The softswitch checks the organization’s registration status on the downstream carrier and either attaches the registered RCD payload — the branded experience — or drops it silently, in which case the recipient sees the attestation result and any CNAM name on file.

Per-number brand override

The organization default paints every outbound call the same brand. Where you run several brands — an agency dialing on behalf of clients, or one business with distinct campaign brands per number — set a per-number profile on the DID instead. The profile writes against the number’s own metadata, and the outbound resolver merges it: the profile’s display name, logo, and reason-for-call override the organization default for that one number. A blank reason-for-call inherits the organization’s reason; the carrier-registration list always stays the organization-level, operator-managed value, so a per-number profile cannot self-attest carriers. Precedence reads three ways:
  • Profile enabled and fully-specified (name + logo). The profile assets render, and the organization default doesn’t.
  • Profile disabled or incomplete (missing name or logo). The organization default renders, unchanged.
  • A profile edit follows the same verification lifecycle as the org default. Rendering new assets resets the per-brand verdict to unverified until review completes.
This is the surface for mixed-brand fleets. If every outbound number should wear one brand, leave profiles unset and the organization default applies.

Failure modes

  • RCD silently disabled — no A-attested number. Full attestation requires the from-number to be an active number your organization owns. A caller ID you don’t own falls to partial or gateway attestation, and the call never carries RCD. Check the posture and an A-eligible number first.
  • RCD enabled but required fields missing. RCD with a blank display name or logo URL is a misconfiguration; the resolver skips the headers rather than send empty. Save a complete brand set and re-read the saved value — the write-time validator rejects it with 422 at the API, or the skip happens silently on the dial path.
  • The carrier isn’t registered, or doesn’t support RCD. The payload drops silently on that call. Check the per-carrier registration list on the branded-calling surface and the branded-calling team’s queue; where registration is still open, the brand can’t render until it completes.
  • Brand assets changed and unverified. A saved name/logo/reason resets verification to unverified until review completes. The brand renders only after review; a partial save of one asset still triggers re-review on the whole rendered set.
  • A stale or authenticated logo URL. The handset fetches the logo URL itself; a URL behind auth, or one that expired since you saved it, renders nothing. The write-time safeHttpsUrl check guards http and loopback hosts, but it cannot know an expiring signed URL — re-point the field at a stable public URL.
  • Hold-out is off when you want the experiment. holdout_pct preserved on a PUT that omitted it is by design; a form that “saves everything” silently can show holdout_pct: 0 only when it sent a number — re-set it explicitly, or omit the field to keep the stored experiment untouched.
  • Per-number override not applying. An incomplete per-number profile (missing name or logo) falls back to the organization default — the profile doesn’t error, it just doesn’t take over. Check both required fields on the profile.

See also