Assemble your STIR/SHAKEN attestation posture
This guide is the walkthrough form of the STIR/SHAKEN attestation posture concept page: it assembles the posture in the order the resolver applies it, with worked curl calls at every step. The hard problem — landing at attestation level A on your outbound numbers — is not one toggle. It is seven small surfaces working in the right order. Run the steps top-down; steps 1–4 raise the level your traffic signs at, steps 5–7 make the resulting posture visible and track it over time, and the troubleshooting hooks at the end close the loop when reality doesn’t match the posture you chose.How the parts fit
Before the steps, the model in one picture:
Signing itself never happens on Orbit. The platform signals the resolved
level on the outbound INVITE; Devotel’s wholesale softswitch — the carrier
of record — signs the PASSporT at exactly the level the platform signals.
For the full signing model, see
STIR/SHAKEN attestation.
Step 1 — Resolve ownership first (the A/B/C ladder)
The dial-time resolver walks a fixed ownership order, before any policy is consulted:- Owned number → A (full). A caller ID that is an active number your organization owns through Orbit — purchased on-platform or ported in and billed to your org — attests at A. This is the only path to full attestation.
- Leased pool number → B (partial). A pool number with an active assignment to your org attests at B. Orbit authenticates your org, but pool ownership is not your verified right-to-use.
- Anything else → C (gateway). A verified external caller ID, a hosted or BYON number you control but do not own in Orbit, or an unattributable caller ID attests at C — the weakest signal and the one downstream carriers most often label “Spam Likely.”
{ "source": "owned" | "leased" } off the posture snapshot next to the
level calls from that number actually attest at — the snapshot is the truth
source, not your intuition about what the org holds.
No step on this page substitutes for Step 1. If answer rates matter,
steps 2–4 refine the posture for numbers the org already owns or
legitimately controls; they never leapfrog a non-owned number to A.
Step 2 — Run the delegate-certificate lifecycle (BYON: C → B, never A)
A delegate certificate (ATIS-1000092) is the artifact your service provider hands you to authorize specific numbers you control but do not own in Orbit. Registering it with Orbit raises the covered numbers from C to B — partial, never full. The ceiling is deliberate: the certificate is a tenant-supplied artifact, Orbit does not cryptographically validate its chain, and the covered-number list you record is free-form input not bound to the certificate’s real TNAuthList — so B (“customer authenticated, number authorization not provider-verified”) is the correct rating for that evidence. A self-registered artifact must never be able to spoof full attestation.Register a certificate
Obtain the PEM chain from your provider, then register it with its coverage list and validity window:start <= end. Write-time failures are precise:
422 INVALID_CERTIFICATE— no parseable PEM certificate block incertificate_pem(wrong encoding, truncated chain, or a non-certificate payload).422 INVALID_COVERAGE_RANGE— a range hadstart > end.422 VALIDATION_ERROR— a malformed field (non-E.164 number, invalid timestamp).409 DELEGATE_CERT_DUPLICATE— the same chain fingerprint is already registered; the numbers already attest at its level.409 DELEGATE_CERT_LIMIT— the 50-certificates-per-org cap is full; revoke an unused certificate first.
Watch the effective status, not the submission time
The registry derives each certificate’s effective status live:
A certificate that flips to
pending, expired, or revoked stops
covering its numbers, and those numbers fall back to their ownership-based
level at the next call — with no call blocked and no error emitted. Read
the registry with:
Renew before the window closes
Re-register a renewed chain before the current certificate’snot_after passes — the drop happens at the flip, not after it. Revoke a
certificate you no longer control with:
Retirement is ownership
A delegate certificate is the gap-fill, not the destination. The permanent fix for a covered number is porting it into Orbit (Step 1): once ownership settles, the coverage is redundant and the certificate can be revoked.Step 3 — Set the inbound verification floor (per-DID policy)
Inbound calls arrive with STIR signalling (a pre-verifiedVerstat result,
or a raw Identity header), and Orbit parses it. Two floors apply:
- Org-level —
inbound_min_verification(Step 5) decides which inbound signature levels count as verified in your posture snapshot. Reporting only; it never rejects a call. - Per-DID minimum attestation on the inbound route is the hard floor: when a route’s minimum attestation is set, inbound calls whose parsed level falls below it are declined with SIP 603 before routing.
unknown) as below any letter floor, setting the per-DID floor
rejects unsigned callers as well as ones that simply failed signing — leave
the floor unset (the default) to admit any signed call regardless of level,
or set it only on DIDs where you deliberately want the stricter posture. A
rejected inbound call carries a readable 603 Decline reason and
rejection is observable per call, before any media path opens.
The per-DID floor applies to inbound only. It never affects outbound
attestation, outbound routing, or outbound signing — those resolve in
Steps 1–2 and the policy in Step 5.
Step 4 — Wire branded calling (RCD) with a CNAM fallback per DID
Rich Call Data (RCD) is the STIR/SHAKEN extension that renders your verified brand on the recipient’s handset — display name, logo, and reason-for-call — on A-attested calls only. Delegates at B, and unattributed C, never carry it. RCD is the posture’s payoff surface: the handset treatment that actually lifts answer rate on owned numbers.Org-level configuration
Set the org default (owner/admin) — the same surface as Settings → Voice → Branded calling:display_nameis 1–40 characters (carriers truncate longer at the wire).reason_for_callis up to 60 characters (the strictest downstream cap).logo_urlmust be a public, TLS-served, stable PNG/JPEG/WebP URL — no authentication headers, nohttp://, no internal hosts. An out-of-spec URL is a422, not a stored-and-later-failing config.holdout_pct(optional, 0–50) withholds RCD from that fraction of otherwise-branded calls to measure answer-rate lift honestly — a randomized control, not a before/after. Omitting it leaves a running experiment untouched.
enabled or adjusting
holdout_pct alone does not reset the verdict.
Per-DID override and the CNAM fallback
The org-level brand paints every outbound number; a per-number profile on the DID overrides the org default for that one number, so a multi-brand fleet can carry a caller’s brand only on their numbers. The override precedence:- Profile enabled and fully specified (name + logo) → the profile assets render.
- Profile disabled or incomplete (missing name or logo) → the org default renders, unchanged.
- Carrier not registered → RCD drops silently for that call; the recipient sees plain attestation plus any CNAM name on file. That CNAM record is the fallback label, not a second brand.
- RCD renders — verified brand on the handset.
- RCD not carried (non-A attestation, unregistered carrier, incomplete profile) — plain attestation result, plus the CNAM name if one is registered.
- No CNAM either — the bare number, and the spam-likely treatment downstream carriers hand generic traffic.
Step 5 — Set the reporting policy (target level, downgrade handling, reporting floor)
The org-level attestation policy declares what you intend (target level), what to do with below-target traffic (downgrade handling), the inbound signature floor treated as verified for fraud posture, and whether failed/unsigned inbound calls count as spoof-risk. It never gates a call — it drives the posture snapshot’s measurement.
Writes are partial — a write that names only
target_attestation
leaves the inbound floor and the spoof-risk flag untouched. Reads
(GET /compliance/attestation/policy) always return 200 with a complete
policy object; an org that has never set one gets the safe defaults. The
intent field here is the one a tenant sets on the dashboard surface
(Settings → Compliance → Attestation) or over this endpoint — always the
same store either way. Invalid values are a 422 and every successful
write lands in your audit log. Owner/admin can write; any member can read.
The policy is reporting intent, not a gate. Setting a target while
your traffic runs on leased pool numbers (B) does not raise or lower what
gets signed — the softswitch signs at exactly the level the platform
attests, and your posture snapshot simply starts flagging those numbers
as below target. Do not PUT a higher target hoping the level follows; the
level follows ownership (Steps 1–2).
Step 6 — Read the posture snapshot
GET /compliance/attestation/posture is the read-only measurement you
assemble everything against. It answers the two questions this guide is
built around at once:
originating.numbers[]lists each originating number with the level calls from it actually attest at (owned→ A,leased→ B), andmeets_targetcompares that to your Step-5 target. The list caps at 500 numbers (numbers_truncatedtells you when you hit the cap) so a sender with thousands of DIDs sees totals first and specific held-back identifiers next — not an aggregate hiding the offender.inbound.summaryclassifies the last 30 days of inbound calls to DIDs your org currently owns: signed at-or-above the floor →verified; signed-below-floor or off-net →unverified; failed or unsigned →spoof_riskwhen the flag is on, elseunverified.verified_rateis the verified share of all inbound calls, ornull(not zero) when the window had no inbound traffic.
Step 7 — Track attestation trajectory with attestation analytics
Steps 1–6 assemble the posture and photograph it. The two analytics endpoints turn that photograph into a film: historical rollups over the calls your org actually placed and received, so you can watch the attestation mix move after a change, prove what a higher level buys, and find out why a number signed lower than it should. Both are read-only, org-scoped observability over traffic you generate and receive — they measure, never gate, and nothing here imposes a floor on your posture.Outbound: GET /api/v1/numbers/attestation-analytics
totals— every outbound call in the window, how many answered, and the overallanswer_rate(null, not zero, when the window holds no calls).by_level— the A/B/C/unknown distribution, always in that order. Each tier carries itstotal,answered,answer_rate, itsshareof all outbound calls, andanswer_rate_lift_vs_c: that tier’s answer rate minus the C tier’s, in rate points. That lift is the measurable payoff of Steps 1–2 — the answer-rate difference full attestation buys over gateway-level signing. A tier with no calls reportsnullrates and anulllift rather than a misleading zero.downgrade— the downgrade-cause breakdown: how many outbound calls in the window carried an attestation downgrade (cli_attestation_downgrade— a legally-usable-but-unattested caller ID), as a share of all outbound calls and asby_causecounts. Expecttotal: 0and an emptyby_causewhen nothing downgraded; new causes slot into the same array without a contract change.trend— the A/B/C/unknown mix per period across the window: hourly buckets on24h, daily on7d/30d/90d. This is the series that shows a regression as it happens, not after the quarter closes.
window to 24h, 7d, 30d, or 90d; omitted, it defaults to
30d. Any other value is a 422 naming the four accepted windows.
Inbound: GET /api/v1/numbers/inbound-attestation-analytics
by_level— the A/B/C/failed/none/unknown distribution.failedis a signature that was present but failed verification, the strongest spoof signal;noneis a caller whose carrier opted out of signing;unknownis off-net traffic with no STIR/SHAKEN signalling at all. The lift column here isanswer_rate_lift_vs_a— each tier’s answer rate minus the fully-verified A tier’s — so a positive lift onfailedornonemeans your org answers unverified callers more often than verified ones, a fraud-exposure signal on its own.spoof_risk— the verification-failed plus unsigned calls as a share of all inbound and asby_causecounts (verification_failed,unsigned). This is the Step-5flag_unverified_inboundintent, measured over time.trend— the inbound attestation mix per period. A risingfailed/unknownshare is spoofed inbound or a degradation in how upstream carriers sign toward you; a falling A share is a carrier signing-quality regression to take to the terminating side.
window values apply, with the same 30d default and 422
on anything else.
Scope: your org’s DIDs, nothing else
Both endpoints scope to DIDs currently assigned to your org, and a call only counts toward a DID while that assignment was in force — a number your org claimed last week does not import its previous owner’s call history. The inbound endpoint scopes on the called number, the outbound one on the calling number. In the API reference’s words, the rollup is “scoped to the caller org’s owned DIDs (a sibling subaccount never sees another org’s mix)”: two subaccounts under the same tenant each see only the traffic on their own numbers. Reads need thenumbers:read scope.
Worked example — spot a stuck delegate certificate on the 7d trend
A BYON block rides a delegate certificate (Step 2) that lifts its numbers to B untilnot_after passes, when coverage ends and the numbers fall
back to C at the next call — silently, with no error on any call, exactly
as Step 2 describes. Watch for it in the outbound analytics:
- Baseline before the expiry:
curl ".../attestation-analytics?window=7d"shows the covered block’s volume sitting in the B tier — a steadybcount intrend, with the matchingshareon the B row ofby_level. - Let
not_afterpass without renewing. - Pull the same window each day. The C row’s
sharecreeps up bucket by bucket whilebdrains — the signature of coverage ending, not of a one-off signing fault, which would move a single bucket and recover. - Confirm with the registry read from Step 2: the certificate now shows
an effective status of
expired. Renew or re-register (Step 2), or port the block in (Step 1) to make the drop permanent.
a draining into c on trend — is the
owned-number regression to chase with the
downgrade troubleshooting run.
Analytics versus the posture snapshot
Step 6 and Step 7 answer different questions, and a complete posture routine uses both:- The posture snapshot (
GET /compliance/attestation/posture) is point-in-time: right now, per number, which level does each originating number hold against your Step-5 target, and how did the last 30 days of inbound verify against your floor? It is the lever-vs-measurement check. - The analytics endpoints are the trajectory: how the mix, the lift,
and the downgrade and spoof causes moved across
24hto90d. The snapshot tells you where the posture stands; the analytics tell you whether it is moving the way you intended.
Troubleshooting hooks
When the snapshot or the recipient-side treatment disagrees with what you declared, two guided pages pick up from here rather than re-explaining the build:- STIR/SHAKEN attestation downgrade
— the systematic root-cause run for a call that signs lower than your
target: the C ceiling on non-owned numbers, an expired or mis-registered
delegate certificate, a per-number branded override, and carrier
coverage gaps in RCD — plus the fix run for each and the error-code map
(
INVALID_CERTIFICATE,INVALID_COVERAGE_RANGE,DELEGATE_CERT_LIMIT,DELEGATE_CERT_DUPLICATE). - STIR/SHAKEN never measured —
the quick-start for a tenant who has never opened the surface: read the
current policy defaults, put the inbound reporting fields back to the
expected defaults (
inbound_min_verification: "B", the flag on), and run the first posture measurement.
See also
- STIR/SHAKEN attestation checklist — the pre-send self-assessment that audits the five reads this guide assembles (floor, brand, signature, crosswalk, traceback) before a tenant entrusts numbers to the dialer; the shared-chain wire across the routing and the failure-chain matrix route back here.
- STIR/SHAKEN attestation — what the A/B/C levels mean, where Orbit signals the level, and where the Devotel softswitch signs it.
- Attestation posture (concept) — the single concept page this walkthrough runs.
- Numbers API — the API reference
group carrying both Step-7 endpoints,
GET /numbers/attestation-analyticsandGET /numbers/inbound-attestation-analytics, with their full request and response schemas. - Branded calling — the RCD surface the payoff step wires.
- CNAM & caller ID — the fallback label the branded- calling step pairs with.
- The STIR/SHAKEN attestation model — PASSporT flow, delegated attestation, and where the gate surfaces.