---
title: "Telephony Config"
method: GET
path: "/telephony/config"
tags: ["telephony"]
---

# Telephony Config

`GET /telephony/config`

## Request

- Base URL: `https://api.verdun.ai` (the document declares no server; this is the origin it was published from)
- URL: `https://api.verdun.ai/telephony/config`
- Auth: HTTP bearer

Whether telephony is connected — ops-view renders the notify-owner and
dispatch-call cards in a 'not connected yet' state (matching the voice-down
pattern) until the provider credentials land.

THE TWO FLAGS HAVE DIFFERENT PROVIDERS AND DIFFERENT GATES: sms_enabled
tracks Surge (SURGE_* env), voice_enabled tracks Twilio (TWILIO_* env)
plus the DISPATCH_CALLS_ENABLED launch gate, which stays off until operator
callback numbers are verified with the customer. The response shape is
unchanged by the SMS provider swap, so ops-view needs no update.

THE CONSENT FIELDS ARE ROLE-SPLIT, AND THE SPLIT IS A TENANCY BOUNDARY,
not tidiness. Every operator needs to know that SMS is currently refusing
sends — otherwise the notify-owner card shows a 503 with no explanation —
but the DETAIL is account-wide consent state:

- `sms_paused` (EVERY operator): a plain boolean, the minimum the card
  needs. True when an unattributed opt-out is holding the gate closed.
- `sms_unresolved_optout_count` (OWNER ONLY): the exact number of
  outstanding opt-outs. `sms_suppressions`/`sms_optout_events` have no
  tenant column by design — a STOP is a fact about a phone number against
  our single shared Surge sending number — so this count spans EVERY
  tenant on the account. A site-scoped or read-only operator polling it
  could watch STOP activity at other customers, which is exactly what the
  owner-only consent routes exist to prevent; leaking the same state
  through a config probe would have made those guards decorative.
- `sms_unresolved_stop_gate_enabled` / `sms_positive_consent_gate_enabled`
  (OWNER ONLY): deployment posture. Not secret, but not a tenant
  operator's business, and grouped with the count so the split is one rule
  rather than three judgements.

`sms_paused` is derived from the SAME predicate the gate uses, so it can
never disagree with the behavior an operator is seeing.

## Response `200`

Successful Response

- object

---

[API](https://skmtc.dev/verdun/apis/verdun-api.md) - [All operations](https://skmtc.dev/verdun/apis/verdun-api/llms.txt) - [OpenAPI document](https://skmtc.dev/verdun/apis/verdun-api/revisions/35a2a6ebedda?raw)
