# How to use the Telnyx Support Agent

The Telnyx Support Agent answers support and troubleshooting questions about
your Telnyx account over [A2A](https://a2a-protocol.org/). It is built for
autonomous agents: your agent sends a question, polls for the answer, and gets
back prose grounded in Telnyx documentation and in your own account data.

Read this runbook before your first request. It covers what the agent can and
cannot do, how to authenticate, how to phrase a question so it can be answered,
and how the request lifecycle actually behaves.

---

## 1. What it can do

**Answer documentation questions.** Telnyx products, APIs, features,
configuration, and recommended setup. No account data required. Answers draw
on:

- [support.telnyx.com](https://support.telnyx.com): the Support Center,
  configuration guides, FAQs, and troubleshooting articles
- [developers.telnyx.com](https://developers.telnyx.com): developer
  documentation: API references, tutorials, and implementation guides
- [telnyx.com](https://telnyx.com): product detail, use cases, and blog content

**Troubleshoot your account.** When authenticated with a Telnyx API key, the
agent inspects the relevant resources in your account, read-only, and answers
in the context of what it finds. Everything is scoped to the authenticated
organization.

**Create support tickets** (the `create-support-ticket` skill). When an issue
needs a human, the agent can open a support ticket on your behalf and returns
the ticket ID and link **in the answer itself**, so your agent can surface or store it. Only **one ticket per
conversation** is created: asking again in the same context returns the
existing ticket rather than opening a second. The agent keeps answering after
escalating.

**One ticket per conversation means one ticket per `contextId`.** If you have a
second, unrelated issue, start a new conversation with a new `contextId`. That
is a separate session and gets its own ticket. Do not reuse a context that has
already escalated and expect a second ticket from it.

**General troubleshooting** (the `troubleshoot` skill) works from read-only
inspection of your account configuration and resources, across any Telnyx
product on your account: voice, messaging, numbers, connections, wireless, and
others. It is broad but shallow, so use it when you do not yet know which product
is at fault, or when nothing more specific applies.

Its coverage broadens over time, so do not treat the products named above as a
closed list. If your question is about a Telnyx product not mentioned anywhere
in this runbook, ask it here rather than assuming it is unsupported.

On the card, the specialist skills are listed **before** the general ones. If
your client selects the first matching skill, that ordering routes you to the
deeper capability rather than to the fallback.

**Look up public prices** (the `public-pricing` skill). The agent reads current
Telnyx list prices live from the public pricing API rather than from
documentation, which goes stale. Name the product, and the two-letter country
code for anything priced per country.

What comes back is the **public list price**. It is not your negotiated or
committed rate, not an invoice or account balance, and not a quote. Some
destinations are priced by rate deck rather than a single figure; those are
identified as rate-deck entries instead of being given a number. For what you
were actually charged, or for billing and refunds, open a support ticket.

If the pricing API is unavailable, the agent falls back to documented pricing
and tells you the figure may not reflect current rates. It will not refuse a
pricing question because a tool is down.

**Find and file feature requests** (the `soundboard` skill). The agent searches
the public Telnyx Soundboard for existing feature requests, reports their status
and vote count, files a new one when nothing matches, and adds your vote to an
existing request. It returns the portal link for anything it finds or creates,
and can point you at the Soundboard itself at
[portal.telnyx.com/#/soundboard](https://portal.telnyx.com/#/soundboard), which
is the only Soundboard address: there is no page for it on telnyx.com.

Search by keyword, and narrow by **product area** or by **status**. A request
is `open`, `planned`, `declined`, `shipped`, or `merged`, so you can ask what
has already been built as well as what is proposed: "which SIP Trunking
requests have shipped?" is a valid question.

Creating and voting are recorded **against your own Telnyx account**, so your
vote counts as yours and the agent can tell you whether you have already voted
on a request. Ask the agent to search before it
files anything: duplicate requests split the vote count that decides what gets
built.

A feature request is **not a support ticket**. It carries no SLA, no
commitment, and no delivery date; it is a signal of demand that Telnyx weighs
when planning. Something broken or misconfigured is a ticket, not a request.

**Report a Mission Control Portal defect** (the `portal-defect-report`
skill). If the Mission Control Portal UI at
[portal.telnyx.com](https://portal.telnyx.com) is visibly broken or has
regressed, the agent hands the report to the team that owns the portal.

This skill is unusually strict about what it accepts, because a report that
cannot be investigated is worse than no report. Include all four of these:

| Include | Example |
|---|---|
| The affected **page or flow**, with its **URL** where you have it | "the Numbers page, `portal.telnyx.com/#/numbers/my-numbers`", "the messaging profile editor" |
| What you **expected** to happen | "it should keep the selected country filter" |
| What **actually** happened | "the filter clears and every number is listed" |
| How to **reproduce** it | "filter by country, then go to page two" |

Describe **one defect per report**. A report missing any of the four is
answered with a request for the rest, costing a round trip.

Paste the **URL** of the page you were on wherever you can. A page name can
match several routes, while the address identifies exactly one, which is the
difference between a defect being reproduced first try and being sent back for
clarification.

It is for the **Mission Control Portal UI** being broken, not the service
behind it: a failing call, a rejected campaign, or a stuck port belongs to the
specialist skills below, whichever interface you noticed it in. It is not for missing functionality (that is `soundboard`), for account
or environment configuration, or for behaviour that is working as designed.

The answer carries a **tracking reference** for the report. Quote it if you
follow up. Do not open a separate support ticket for the same defect: the
report is already with the team that owns the portal, and a ticket alongside it
just puts a second person on something already being worked.

Beyond that, the agent has deeper specialist coverage in six areas, each
advertised as a discrete skill on the agent card. **When your question falls in
one of these and you have the identifier, say so explicitly**, because the specialist
path returns far more detail than general troubleshooting will:

| Skill | What to ask about | Identifiers to supply |
|---|---|---|
| `porting-lookups` | Order status, FOC dates, carrier, rejections and exceptions, required documents, portability, activation status | **Support key** (`SR_XXXX`) for a specific order, or the **phone number** for number-scoped lookups. General porting process questions need no identifier |
| `10dlc-campaign-lookups` | Declined campaign diagnosis, campaign field generation and linting, opt-in website validation, registration requirements, brand failures, sole-proprietor OTP | **TCR campaign ID** or **TCR brand ID** to investigate a specific registration. General 10DLC requirements and compliance questions need no identifier |
| `voice-call-troubleshooting` | Call failures, one-way or missing audio, dropped calls, quality issues, SIP/media/application-layer root cause, multi-leg topologies | **Call ID**: RTC session ID, call session ID, call leg ID, or call control ID |
| `public-pricing` | Current public list prices across Telnyx products, read live from the pricing API | **Product name**, plus the **two-letter country code** for anything priced per country. No account identifier needed |
| `soundboard` | Searching, reading, filing, and voting on Telnyx feature requests; filter by product area or status (`open`, `planned`, `declined`, `shipped`, `merged`) | **What the feature is**, in your own words. No account identifier needed: votes and requests are attributed from the identity that authenticated the request |
| `portal-defect-report` | Reproducible broken or regressed behaviour in the Mission Control Portal UI (portal.telnyx.com) | **Page or flow** (with its **URL** where you have it), **expected** behaviour, **actual** behaviour, and **reproduction steps**. All four, or the report cannot be investigated |

Supplying the right identifier in the first message matters more than anything
else you can do. Without one the agent has to ask for it, costing a full round
trip, and the identifier is product-specific, so a call ID will not help a
porting question.

Five scope notes. Porting, 10DLC, and pricing all answer **general knowledge
questions** with no identifier at all, so "what are the common reasons campaigns
get declined?" is a valid first message.

**Billing, refunds, credits, fees, and payment decisions are out of scope.**
`public-pricing` answers what a product costs on the public price list, but
anything about what your account was actually charged needs a human and will be
handed off.

**Ask pricing as its own message.** Each specialist covers its own area, and
pricing is `public-pricing`'s. A question that bundles two areas together, such
as "why was my campaign declined and what does it cost?", is answered as one
blob and the pricing half may be answered less precisely. Splitting it into two
messages gets you the specialist path for each.

**A missing feature is a request, not a ticket.** If Telnyx does not build
something yet, `soundboard` is where it goes: opening a support ticket for it
puts a human in front of something no human can action. If something exists but
is not working, that is the other way round.

**Broken, missing, and misconfigured are three different things**, and they go
to three different skills. Something that used to work and now does not is a
defect (`portal-defect-report` for the Mission Control Portal UI, the product
specialists for everything else). Something Telnyx has never built is a feature request
(`soundboard`). Something set up wrong on your account is a support question,
and `troubleshoot` will diagnose it. Saying which of the three you mean, in
those words, gets you the right path in one message.

## 2. What it cannot do

The agent has **read-only** access to your account. It cannot make changes,
provision services, update configuration, or perform any other write action
against your account through the A2A interface. Asking it to "fix" something
will get you a diagnosis and a recommendation, not a change.

Three things it can write, none of which touches your account: it can open a
support ticket (`create-support-ticket`), file or vote on a feature request
(`soundboard`), and submit a portal defect report (`portal-defect-report`).
All three are recorded as coming from you.

It also cannot answer about accounts other than the one whose API key
authenticated the request.

It cannot withdraw a feature request. Nothing in the A2A interface deletes one,
so a request filed by mistake has to be taken down by the Soundboard team. Ask
the agent to search first and vote on an existing request where one fits.

Filing or voting on a feature request commits Telnyx to nothing. There is no
SLA, no acceptance, and no delivery date attached to a request or to any vote
total it reaches.

### Looking ahead

We expect to support some write actions in future, introduced **per product**
rather than as a blanket capability, and gated behind explicit approval rather
than performed on the agent's own initiative.

Nothing here is committed: which products, which actions, and what the approval
mechanism looks like are all still to be confirmed, and there is no timeline.

Build against read-only today. When write support does arrive it will be
announced as new skills on the [agent
card](https://api.telnyx.com/v2/support_agent/support/a2a/.well-known/agent-card.json),
so an integration that reads the card at connect time will see the change
without needing to re-read this runbook. Read-only behaviour will not change
underneath you. The current skills keep their current semantics.

## 3. Connecting

**Endpoint**

```
POST https://api.telnyx.com/v2/support_agent/support/a2a
```

**Agent card** (no authentication required)

```
GET https://api.telnyx.com/v2/support_agent/support/a2a/.well-known/agent-card.json
```

Fetch the card to discover the current skill list programmatically. It is the
authoritative statement of what the agent supports; this runbook explains how
to use it well.

**Detecting changes.** The card carries a `version` field. When it changes, the
card has changed, but A2A defines no changelog, no diff endpoint, and no way
to retrieve a previous card, so `version` tells you *that* something moved, not
*what*. If you care about the difference, **cache the card you last saw and
diff it yourself**; comparing the `skills` array by `id` is usually enough to
spot added or withdrawn capabilities.

This agent versions its card with SemVer, and the number means:

| Change | What it signals |
|---|---|
| **Patch** (`1.1.0` → `1.1.1`) | Wording only. No capability or behaviour change; nothing to do |
| **Minor** (`1.1.0` → `1.2.0`) | Backward-compatible additions, typically new skills. Existing integrations keep working; re-read the card if you want the new capability |
| **Major** (`1.1.0` → `2.0.0`) | A skill was removed or changed meaning, or the usage contract changed. Re-read the card and review your integration |

Do not confuse `version` with `protocolVersion`. The latter is the version of
the A2A specification the agent implements, and moves independently.

A sensible default is to re-fetch the card periodically (daily is plenty; it
changes rarely) and compare `version` against the copy you hold. Dated release
history is in the [changelog](#9-changelog) at the end of this runbook.

Skill `id` values are stable and safe to match on. Skill `name` and
`description` text may be reworded without a behaviour change, so do not treat
those as identifiers.

**Authentication.** Send a Telnyx API key as a bearer token:

```
Authorization: Bearer YOUR_TELNYX_API_KEY
```

Create or copy a key in the Mission Control Portal under
[API Keys](https://portal.telnyx.com/#/api-keys). Any valid key for the account
works; the agent resolves your organization from it, which is what scopes every
answer to your account.

The key must be issued in advance by a human with portal access. There is no
way for a calling agent to obtain one through this interface. If you do not
have a Telnyx account yet, [sign up](https://telnyx.com/sign-up) first.

Treat the key as a credential: it grants read access to your account data
through this agent, so store it in a secret manager rather than in the agent's
prompt or source.

**Protocol.** JSON-RPC 2.0. Transport is `JSONRPC`; protocol version `0.3.0`.
Input and output are `text/plain`.

## 4. Sending a request

```json
{
  "jsonrpc": "2.0",
  "id": "1",
  "method": "message/send",
  "params": {
    "message": {
      "role": "user",
      "messageId": "b6f1e0c8-7a34-4d92-8c51-1f0a9d3e7b45",
      "parts": [
        {
          "kind": "text",
          "text": "Why was TCR campaign C1A2B3C declined, and what do I need to change before resubmitting?"
        }
      ]
    }
  }
}
```

The response returns a task with an `id`, a `contextId`, and a non-terminal
state. **The answer is not in this response.** Poll for it.

### Keeping the conversation together

The first request above omits `contextId`, so the agent generates one and
returns it on the task. **Capture that value and send it on every follow-up in
the same conversation:**

```json
{
  "jsonrpc": "2.0",
  "id": "3",
  "method": "message/send",
  "params": {
    "message": {
      "role": "user",
      "messageId": "c47d2b91-05a6-4e38-9b7f-3e8a1c6d0f52",
      "contextId": "CONTEXT_ID_FROM_THE_FIRST_RESPONSE",
      "parts": [
        {
          "kind": "text",
          "text": "The campaign is still failing after I updated the opt-in page. What else should I check?"
        }
      ]
    }
  }
}
```

Note the **new `messageId`** — that is per-message, and reusing one is treated
as a retry of the earlier message. The `contextId` is what stays constant.

Omitting `contextId` starts a **new conversation every time**, which silently
costs you three things:

- **History.** The agent does not see the earlier turns, so a follow-up that
  says "it is still failing" has no idea what "it" refers to.
- **One-in-flight cancellation.** Parallel requests no longer supersede each
  other, because that rule is scoped to a context.
- **One ticket per conversation.** Each turn becomes its own conversation and
  can open its own ticket, so a single issue may end up with several.

You may also generate the `contextId` yourself and send it on the first
request. Either approach works, as long as it stays constant for the life of
the conversation and is unique per conversation. Keep it to 36 characters or
fewer (see [§6a](#6a-current-limitation-contextid-length)).

## 5. Getting the answer: poll `tasks/get`

Streaming is not supported: the agent card advertises `streaming: false`, and
`tasks/resubscribe` is rejected. Polling is the only delivery mechanism.

```json
{
  "jsonrpc": "2.0",
  "id": "2",
  "method": "tasks/get",
  "params": { "id": "TASK_ID_FROM_MESSAGE_SEND" }
}
```

Poll until the task reaches a terminal state:

| State | Meaning |
|---|---|
| `completed` | Answer is at `result.status.message.parts[]` (see below) |
| `failed` | Authentication produced no verified organization, or the run errored |
| `rejected` | A duplicate `messageId` was reused; the message names the original task to poll |
| `canceled` | Superseded by a newer message in the same context, or interrupted |

The answer lives at **`result.status.message.parts[]`**, under the status, not
at `result.message` or `result.parts` — neither of those exists. A completed
`tasks/get` response looks like this:

```json
{
  "jsonrpc": "2.0",
  "id": "poll-1",
  "result": {
    "id": "cff49299-c68d-4017-bf47-ad6f1c06f9c6",
    "kind": "task",
    "contextId": "6f2b8d14-93ae-4c07-b5d1-0a7e2f4c8b36",
    "status": {
      "state": "completed",
      "message": {
        "role": "agent",
        "parts": [{ "kind": "text", "text": "The answer text." }]
      }
    }
  }
}
```

Concatenate the `text` of every part whose `kind` is `text`.

Poll about every 2 seconds and keep polling while the task remains non-terminal.
A task still processing after a minute is normal: account-scoped investigations
take longer than documentation questions, because the agent is querying live
resources, and a specialist lookup that fans out to porting, 10DLC, or call
diagnostics can run for **several minutes**.

Polling more frequently does not make the investigation run faster; it only
reduces the delay before you observe a task that has already completed.

Give up late rather than early. `message/send` is not idempotent (see below), so
abandoning a task and re-sending starts a **second live investigation** instead
of retrying a cheap read. Set your overall deadline in minutes rather than
seconds, and if you need to stop polling, retain the original task ID and resume
later with `tasks/get`.

## 6. Request lifecycle rules

These behaviors most often surprise a first integration.

**`message/send` is not idempotent.** If you have a task ID, **poll
`tasks/get`**; do not re-send. A naive retry starts a second, independent
investigation.

**If the send itself timed out you have no task ID**, so polling is not an
option. Re-send with the **same `messageId`**.

**Reuse the same `messageId` on any re-send.** It is treated as an idempotency
key: a repeat with a `messageId` your organization has already used returns the
*original* task rather than starting new work, or returns a `rejected` task
whose message names the original task ID for you to poll. Re-sending with a
*new* `messageId` starts duplicate work. This only protects you if you preserve
the ID across retries; it is not ambient protection, so generate the ID once and
hold it for the lifetime of the retry loop.

**One request in flight per context.** Sending a newer message in the same
context **cancels the previous task**. Do not fan out parallel questions on one
context ID. Either wait for each to finish, or use separate contexts. This
rule only applies if you actually reuse the `contextId`; see
[Keeping the conversation together](#keeping-the-conversation-together).

**`tasks/cancel` is not supported.** It returns
`UnsupportedOperationError` (`-32004`) for every task state. Let tasks finish,
or supersede them with a newer message in the same context.

**A JSON-RPC error still returns HTTP 200.** The transport succeeded even when
the request did not. Check for an `error` member in the JSON-RPC response body
before assuming a send worked. A caller that only checks HTTP status will go
on to poll a task that was never created.

## 6a. Current limitation: `contextId` length

> **Temporary.** Tracked as AIINT-883; this section will be removed once the
> fix ships.

The A2A specification treats `contextId` as an opaque string, and long term the
Support Agent will too. Today, however, a `contextId` **longer than 36
characters** fails on task creation.

The failure is not obvious from the caller's side:

- HTTP status is `200 OK`
- the JSON-RPC body carries an internal error, `-32603`
- the message is a Postgres `StringDataRightTruncation`, which says nothing
  about `contextId`
- it is fully deterministic, so every retry fails identically

Hashes are the common trigger: a SHA-1 hex digest is 40 characters, a SHA-256
digest is 64.

**Until the fix ships**, keep `contextId` to 36 characters or fewer. A UUID is
36 and is the safest choice. If you derive context IDs from a hash, truncate it
or map it to a UUID on your side.

## 7. Writing a good question

The agent works from what you give it. In order of impact:

**Lead with the identifier, and use the right one.** A TCR campaign ID, a
porting support key (`SR_XXXX`), or a call ID turns a clarifying round trip into
an immediate answer. They are not interchangeable. See the table in
section 1.

You never need to send your account or user ID. The agent resolves your
organization from the API key you authenticated with, and every lookup is
scoped to it automatically.

**Describe the symptom, not your diagnosis.** "Calls to +1 555 0100 fail after
about 5 seconds with no audio" is answerable. "Fix my SIP ALG problem" presumes
a cause and steers the agent away from the real one.

**Ask open questions about capability, not leading ones about a named feature.**
Asking whether a specifically-named feature exists invites the agent to accept
the premise. Describe the outcome you want instead.

**Include the time window** for anything transient, such as call failures,
delivery problems, or throughput drops. "Yesterday around 14:00 UTC" narrows the search
enormously.

**One issue per context.** Bundled questions get bundled answers, and the
one-in-flight rule means follow-ups on a shared context cancel earlier work.
This also governs escalation: a ticket is scoped to its `contextId`, so
separate issues need separate contexts to become separate tickets.

## 8. When to escalate

Ask the agent to open a support ticket when:

- the diagnosis points at something only Telnyx can change;
- the issue needs a write action, which the agent cannot perform today:
  **but check first whether the account owner can make the change
  themselves**. Most configuration exposed in the
  [Mission Control Portal](https://portal.telnyx.com) is self-service, so the
  faster path is usually to relay the diagnosis and the exact change to the
  person who owns the account rather than opening a ticket. Escalate only when
  the change is backend-only, needs Telnyx to act on a carrier's behalf, or the
  portal genuinely does not expose it;
- the answer is a known limitation and you need the case tracked.

Give it the identifiers and the symptom description when you ask, because the ticket
it opens carries whatever context you have supplied.

One ticket is created per conversation. For a separate issue, open a new
conversation with a new `contextId` rather than continuing an already-escalated
one.

## 9. Changelog

Agent card versions, newest first. The card itself carries no release date
(A2A defines no field for one), so the dates are recorded here.

Each entry lists the **full skill set** at that version, so you can tell what a
given card supports without reconstructing it from the diffs.

### `1.4.0`, 2026-08-25

Added one skill: reporting Mission Control Portal defects. Backward compatible: no
skill was removed or renamed, and existing skills keep their behaviour.

**Skills at this version**

| Skill `id` | Name |
|---|---|
| `troubleshoot` | General troubleshooting |
| `ask-docs` | Ask about Telnyx products and configuration |
| `porting-lookups` | Porting lookups |
| `10dlc-campaign-lookups` | 10DLC campaign and brand support |
| `create-support-ticket` | Create a support ticket |
| `voice-call-troubleshooting` | Voice call troubleshooting |
| `public-pricing` | Public pricing lookups |
| `portal-defect-report` | Report a Mission Control Portal defect |
| `soundboard` | Feature requests on the Soundboard |

**Changes**

- **Added** `portal-defect-report`: report reproducible broken or regressed
  Mission Control Portal (portal.telnyx.com) UI behaviour. Needs the affected
  page or flow (with its URL where available), expected behaviour, actual
  behaviour, and reproduction steps: all four, or the report
  cannot be investigated. One defect per report. The answer carries a tracking
  reference, so a follow-up quotes that rather than opening a separate support
  ticket. Not for missing functionality (`soundboard`), account or environment
  configuration, or behaviour working as designed.
- **Changed** `soundboard`: now points Mission Control Portal UI behaviour
  that used to work and no longer does at `portal-defect-report`, since callers routinely
  describe a regression as a feature request. No change to what the skill does.
- **Changed** `troubleshoot`: now names `portal-defect-report` alongside the
  other specialists it defers to. No change to what the skill does.

### `1.3.0`, 2026-08-25

Added one skill: feature requests on the Soundboard. Backward compatible: no
skill was removed or renamed, and existing skills keep their behaviour.

**Skills at this version**

| Skill `id` | Name |
|---|---|
| `troubleshoot` | General troubleshooting |
| `ask-docs` | Ask about Telnyx products and configuration |
| `porting-lookups` | Porting lookups |
| `10dlc-campaign-lookups` | 10DLC campaign and brand support |
| `create-support-ticket` | Create a support ticket |
| `voice-call-troubleshooting` | Voice call troubleshooting |
| `public-pricing` | Public pricing lookups |
| `soundboard` | Feature requests on the Soundboard |

**Changes**

- **Added** `soundboard`: search, read, file, and vote on Telnyx feature
  requests, narrowing by product area or status (`open`, `planned`,
  `declined`, `shipped`, `merged`). Needs no account identifier. Creating and
  voting are recorded against the account that authenticated the request, so a
  vote counts as yours and the agent can tell you whether you have already
  voted. A request carries no SLA, commitment, or delivery date, and cannot be
  withdrawn through this agent.
- **Changed** `create-support-ticket`: now points feature requests at
  `soundboard`, so asking for something Telnyx does not build yet does not
  arrive as an escalation. No change to what the skill does.
- **Changed** `troubleshoot`: now names `soundboard` alongside the other
  specialists it defers to. No change to what the skill does.

### `1.2.0`, 2026-08-25

Added one skill: public pricing lookups. Backward compatible: no skill was
removed or renamed, and existing skills keep their behaviour.

**Skills at this version**

| Skill `id` | Name |
|---|---|
| `troubleshoot` | General troubleshooting |
| `ask-docs` | Ask about Telnyx products and configuration |
| `porting-lookups` | Porting lookups |
| `10dlc-campaign-lookups` | 10DLC campaign and brand support |
| `create-support-ticket` | Create a support ticket |
| `voice-call-troubleshooting` | Voice call troubleshooting |
| `public-pricing` | Public pricing lookups |

**Changes**

- **Added** `public-pricing`: current public list prices across Telnyx
  products, read live from the public pricing API. Needs no account
  identifier. Returns public list prices only, never negotiated rates,
  invoices, or account balances; rate-deck destinations are identified as
  such rather than given a figure.
- **Changed** `10dlc-campaign-lookups`: its scope note still excludes billing,
  refunds, and pricing, which remains accurate for this skill. It now points
  at `public-pricing` and asks for list-price questions as a separate message,
  so the note redirects rather than dead-ending. No change to what the skill
  does.
- **Changed** `troubleshoot`: now names `public-pricing` alongside the other
  specialists it defers to, so a caller with a pricing question is steered to
  the specialist. No change to what the skill does. `ask-docs` is deliberately
  unchanged: documentation is the fallback when the pricing API is
  unavailable, so it must not disclaim pricing.

### `1.1.0`, 2026-08-24

Added four skills: three product specialists plus discoverable ticket
creation. Backward compatible: no skill was removed or renamed, and existing
skills keep their behaviour.

**Skills at this version**

| Skill `id` | Name |
|---|---|
| `troubleshoot` | General troubleshooting |
| `ask-docs` | Ask about Telnyx products and configuration |
| `porting-lookups` | Porting lookups |
| `10dlc-campaign-lookups` | 10DLC campaign and brand support |
| `create-support-ticket` | Create a support ticket |
| `voice-call-troubleshooting` | Voice call troubleshooting |

**Changes**

- **Added** `porting-lookups`: order status, FOC dates, rejections and
  exceptions, document requirements, portability, activation status.
- **Added** `10dlc-campaign-lookups`: declined campaign diagnosis by TCR
  campaign ID, campaign field generation and linting, opt-in website
  validation, brand failures, sole-proprietor OTP.
- **Added** `voice-call-troubleshooting`: SIP, media-plane, and
  application-layer diagnosis by call ID, including multi-leg topologies.
- **Added** `create-support-ticket`: opens a Telnyx support ticket for the
  conversation and returns its number and link in the answer. One ticket per
  conversation. The capability itself is not new; it was previously
  undiscoverable from the card.
- **Changed** `troubleshoot`: renamed to "General troubleshooting"; its
  description now scopes it as the open-ended fallback across any Telnyx
  product and routes callers to the specialist skills when they hold the
  relevant identifier. The `id` is unchanged, so existing matching still works.
- **Changed** `ask-docs`: description clarified as documentation-only, needing
  no account data or identifier. No behaviour change.

### `1.0.0`, initial release

**Skills at this version**

| Skill `id` | Name |
|---|---|
| `troubleshoot` | Troubleshoot Telnyx services |
| `ask-docs` | Ask about Telnyx products and configuration |
