# Create and troubleshoot 10DLC campaigns with the Telnyx Support Agent

Use this runbook when an external bot must prepare, create, inspect, or troubleshoot a customer's 10DLC campaign.

Follow the [Telnyx Support Agent A2A connection guide](https://telnyx.com/support-agent/runbooks/how-to-use-support-agent.md) before using this runbook.

## Public contract

Fetch the [public agent card](https://api.telnyx.com/v2/support_agent/support/a2a/.well-known/agent-card.json) at runtime. For 10DLC preparation and investigation, use the advertised `10dlc-campaign-lookups` capability. Refer to the capability, not to any internal agent, tool, or service that may implement it.

This workflow uses three authenticated surfaces. Prefer the Agent CLI for live
execution when its current command matches the requested operation:

| Surface | Responsibility | May change customer state? |
|---|---|---|
| Telnyx Support Agent over A2A | Explain requirements, validate opt-in evidence, generate and lint campaign fields, and diagnose existing registrations | No |
| [Telnyx Agent CLI](https://github.com/team-telnyx/ai/tree/main/cli) | Preferred executable path for supported 10DLC setup operations | Yes |
| Telnyx 10DLC REST API | Fallback for operations the Agent CLI does not currently expose, including campaign creation under an existing brand and documented edits | Yes |

Use the customer's Telnyx API key through the surface's documented credential
mechanism: `TELNYX_API_KEY` for the Agent CLI and the bearer authorization header
for A2A or REST. Never place the key in a prompt, URL, artifact, source file,
command argument, or log.

## Agent CLI discovery

Install the public package and inspect its current capabilities before execution:

```bash
npm install -g @telnyx/agent-cli
telnyx-agent capabilities
```

For new U.S. Sole Proprietor registration, the relevant command is
`telnyx-agent setup-10dlc`. Read the current
[Agent CLI 10DLC guide](https://github.com/team-telnyx/ai/tree/main/cli#telnyx-agent-setup-10dlc)
before preparing the command. Do not assume a command exists merely because an
HTTP endpoint exists.

The current `setup-10dlc` command has a narrow, important boundary:

- it creates a new U.S. Sole Proprietor brand and a new campaign;
- it can optionally assign an existing phone number;
- it does not buy a phone number;
- it is side-effecting and not idempotent;
- a partial failure can leave the brand already created;
- `ready: true` means the setup workflow completed, not that carrier review is
  complete.

Do not use `setup-10dlc` for an existing brand, a non-Sole-Proprietor entity, a
campaign-only operation, an update, or a resubmission. Use the REST fallback or
human support for those cases until the Agent CLI advertises a matching command.

## Intent routing

Choose one branch:

```text
new campaign -> CREATE
existing campaign is declined, stuck, or incorrect -> TROUBLESHOOT
new U.S. Sole Proprietor brand plus campaign -> prefer Agent CLI setup-10dlc
new campaign under an existing or non-Sole-Proprietor brand -> REST fallback
request to update or resubmit -> TROUBLESHOOT first, then prefer a matching Agent CLI command; otherwise use only a currently documented REST action
missing required identifier -> ask for it; never infer it from a company or brand name
```

## CREATE: prepare and create a new campaign

### 1. Collect the minimum inputs

Do not invent missing facts. Ask only for fields that are not already known.

```text
Telnyx brand UUID:
TCR brand ID, when available:
Business entity type: Sole Proprietor | Private Profit | Public Profit | Non-Profit | Government
Create a new brand, or use an existing brand:
Brand name:
Legal company name, when applicable:
Website:
Support email:
Business phone or sender context:
Use case:
Sub-use cases, when required:
Opt-in method: web | verbal | paper | inbound keyword
Message purpose:
Message flow / opt-in description:
Sample messages:
HELP response:
STOP / opt-out response:
Privacy policy URL:
Terms URL:
Public opt-in URL or paper-evidence URL, when applicable:
Campaign attributes: embedded links, embedded phone numbers, number pool, age gating, direct lending
```

An existing Telnyx brand must be eligible for the requested use case before
campaign creation. Sole Proprietor brands must complete required identity and
OTP verification. Do not silently create a new Sole Proprietor brand when the
customer intended to use an existing brand.

### 2. Ask for current 10DLC requirements

Send a plain-language request through the Telnyx Support Agent. Do not name an internal specialist.

```text
Explain the current 10DLC requirements for a new campaign.

Use case: USECASE
Sub-use cases: ...
Opt-in method: web | verbal | paper | inbound keyword

Return required fields, evidence, consent language, privacy-policy requirements, and use-case-specific constraints. Do not submit or modify anything.
```

Do not fill compliance gaps from model memory. If the A2A result is incomplete or uncertain, ask a focused follow-up or escalate.

### 3. Validate opt-in evidence

For web opt-in:

```text
Validate this public 10DLC opt-in page:
https://example.com/signup

Return the exact elements found, missing elements, hard blockers, and warnings. Do not modify the site or any Telnyx resource.
```

For paper or image evidence:

```text
Validate this 10DLC paper opt-in evidence:
https://example.com/evidence/consent-form.pdf

Return the exact elements found, missing elements, hard blockers, and warnings. Do not submit or modify anything.
```

The evidence URL must be reachable by the service. Never place API keys, OTPs, PINs, approval tokens, or unrelated customer data in it.

Verbal and inbound-keyword opt-in normally do not require website validation unless a URL is part of the evidence.

### 4. Generate and lint the campaign draft

Provide all collected facts in one request:

```text
Generate and lint a 10DLC campaign draft from the data below.

Return:
1. A copy/paste-ready campaign draft.
2. Hard blockers.
3. Warnings.
4. Evidence that was validated.
5. Missing customer-supplied facts.

Do not submit or modify a live campaign.

Brand name: ...
Website: ...
Support email: ...
Business phone or sender context: ...
Use case and sub-use cases: ...
Opt-in method: ...
Message purpose: ...
Message flow: ...
Sample messages: ...
HELP response: ...
STOP response: ...
Privacy policy URL: ...
Terms URL: ...
Opt-in or evidence URL: ...
Campaign attributes: ...
```

Do not proceed while a hard blocker or required fact is missing. Return the blockers to the customer, accept corrected facts, then re-run the relevant validation and lint steps.

### 5. Select the execution path

Prefer the Agent CLI only when all of these are true:

1. The requested outcome is a new U.S. Sole Proprietor brand plus a new campaign.
2. The customer has not asked to use an existing brand.
3. The current `telnyx-agent capabilities` output and README still advertise
   `setup-10dlc` with the required flags.
4. All required facts and compliance evidence are available and the generated
   draft has no hard blockers.
5. The caller can preserve the structured JSON receipt and handle partial
   failure without blindly repeating the command.

Otherwise use the REST fallback. In particular, use the fallback for an
existing brand, standard brand, campaign-only creation, qualification queries,
status operations not exposed by the Agent CLI, or documented campaign edits.
This is a capability boundary, not a preference for handwritten HTTP.

### 6. Obtain explicit creation authorization

Campaign creation is billable and may incur an upfront, non-refundable charge. Before the write:

1. Show the exact Agent CLI command and argument values, or the exact REST
   fallback payload.
2. Show the current fee values available for the selected registration path.
3. State whether the action creates both a live brand and campaign or only a
   campaign, and whether it also assigns a phone number.
4. State that the action accepts the applicable terms and may incur registration
   charges.
5. Obtain explicit customer confirmation for these exact resources, use case,
   content, and fee-bearing action.

Do not infer acceptance from silence. If required fee information cannot be
determined before execution, surface that limitation and use the applicable
human approval or support path. For a REST fallback, set `termsAndConditions` to
`true` only after the customer explicitly accepts the terms for this action.

### 7. Execute with the Agent CLI when eligible

Set `TELNYX_API_KEY` through the caller's secret-management mechanism. Do not put
the key directly in the command. Use structured argument execution when
possible so customer-supplied text is not interpreted by a shell.

Prepare a command with explicit customer values rather than relying on generated
defaults. Omit `--sample-message-2` only when the selected use case does not
require a second sample, and omit `--phone-number-id` when no assignment was
authorized. Despite the flag name, the current command expects the existing
phone number in E.164 form. The command below is a template; never execute it
until every placeholder has been replaced with an authorized value.

```bash
telnyx-agent setup-10dlc \
  --phone "+15551234567" \
  --email "support@example.com" \
  --brand-name "Example Brand" \
  --company-name "Example Legal Name" \
  --vertical "TECHNOLOGY" \
  --website "https://example.com/sms-opt-in" \
  --usecase "CUSTOMER_CARE" \
  --opt-in-method "web" \
  --description "Customer support updates" \
  --message-flow "EXACT VALIDATED MESSAGE FLOW" \
  --sample-message "EXACT CUSTOMER-SUPPLIED SAMPLE" \
  --help-message "EXACT VALIDATED HELP RESPONSE" \
  --stop-message "EXACT VALIDATED STOP RESPONSE" \
  --start-message "EXACT VALIDATED START RESPONSE" \
  --json
```

Execute the exact authorized command once. Treat warnings as findings that must
be reported, not as proof of approval. Preserve the complete structured output,
excluding credentials, including:

- brand ID, name, and status;
- campaign ID and status;
- selected use case and opt-in method;
- submitted message flow and HELP/STOP/START values;
- optional assigned number;
- warnings, step results, and failure details.

### 8. Use the REST API only as a capability fallback

Use the current public API references when the requested operation is outside
the Agent CLI's advertised surface. Do not transcribe raw HTTP requests from
this runbook; construct them from the live API reference or current Telnyx SDK.

For campaign creation under an existing eligible brand, use the current
[Qualify By Usecase](https://developers.telnyx.com/api-reference/campaign/qualify-by-usecase)
and [Submit Campaign](https://developers.telnyx.com/api-reference/campaign/submit-campaign)
references. Preserve returned qualification constraints and fees, and do not
substitute another use case without customer approval.

Before sending:

1. Confirm the request uses the customer-approved Telnyx brand UUID, use case, and campaign content.
2. Include only fields supported by the current API reference.
3. Generate one stable, customer-scoped `referenceId` for this logical creation attempt and preserve it across timeout recovery.
4. Send the customer's API key only in the bearer header.

Treat creation as successful only when the API returns a successful response identifying the affected campaign. Preserve, without transformation:

- Telnyx campaign UUID;
- TCR campaign ID, when present;
- Telnyx and TCR brand IDs, when present;
- submission and campaign status;
- `referenceId`;
- fee or billing metadata;
- response body and request timestamp, excluding secrets.

### 9. Recover safely from failures or timeouts

Neither execution path is safe to repeat blindly.

- If Agent CLI Step 1 created a brand but a later step failed, preserve that
  brand ID and do not rerun `setup-10dlc`; continue through a narrower supported
  path or escalate.
- If a successful CLI or REST response was returned, do not repeat the action.
- If the request timed out after it may have reached Telnyx, use the authenticated list or retrieval APIs to search for the original result before retrying.
- If the current API supports lookup by `referenceId`, use the same value. Never generate a new value to bypass an uncertain result.
- Never retry the non-idempotent Agent CLI setup command as a timeout-recovery
  mechanism.
- If a REST retry is necessary, reuse the exact same logical payload and
  `referenceId`.
- If the outcome cannot be proven, report `execution_state: uncertain` and escalate rather than risking a second billable registration.

### 10. Check campaign and MNO status

Prefer a current Agent CLI status or retrieval command if
`telnyx-agent capabilities` advertises one for 10DLC. Otherwise use the Telnyx Support Agent
for account-scoped diagnosis or the REST fallback references for
[Get Campaign](https://developers.telnyx.com/api-reference/campaign/get-campaign)
and [Get Campaign Operation Status](https://developers.telnyx.com/api-reference/campaign/get-campaign-operation-status).

Report Telnyx, TCR, and MNO status separately. A created campaign is not necessarily approved or provisioned. Never say `active`, `approved`, or `ready to send` unless the current API response supports that statement.

## TROUBLESHOOT: diagnose an existing campaign

### 1. Resolve the public lookup identifier

The public `10dlc-campaign-lookups` contract accepts a TCR campaign ID for a specific campaign investigation.

- If the caller supplies a TCR campaign ID, preserve it exactly.
- If the caller supplies only a Telnyx campaign UUID, prefer a matching Agent
  CLI retrieval command when one is advertised. Otherwise use the authenticated
  [Get Campaign API](https://developers.telnyx.com/api-reference/campaign/get-campaign)
  as a fallback to resolve its `tcrCampaignId`, or ask the caller for the TCR
  campaign ID.
- Never guess an identifier from a brand name or company name.

### 2. Ask for a 10DLC campaign diagnosis

```text
Diagnose TCR 10DLC campaign TCR_CAMPAIGN_ID for the authenticated Telnyx account.

Return:
1. Current Telnyx, TCR, and MNO status.
2. Actual Telnyx or carrier decline reasons, separately from additional lint findings.
3. Current campaign fields relevant to each finding.
4. Website or evidence validation when relevant.
5. Exact current -> proposed field corrections supported by the diagnosis.
6. Customer action, human review, or escalation required.

Do not modify, resubmit, appeal, or create anything.
```

If the diagnosis returns both the Telnyx campaign UUID and TCR campaign ID, preserve both.

### 3. Classify the result

Use the smallest applicable category:

| Result | Bot action |
|---|---|
| Campaign not found | Confirm the identifier and authenticated account. Do not probe another account. |
| Authentication or permission failure | Stop and surface the exact error. |
| Pending with no decline reason | Report the current stage and next check; do not invent a blocker. |
| Telnyx decline | Return the actual Telnyx decline reason and supported correction. |
| MNO rejection | Return the carrier, actual rejection code/reason, and supported correction or escalation path. |
| Additional lint warning only | Label it as a warning, not the cause of rejection. |
| Evidence unreachable or blocked | Report that validation was inconclusive; do not call the site non-compliant solely because the bot could not load it. |
| Correctable through an advertised Agent CLI command | Prepare the exact command and require explicit authorization before the write. |
| Correctable only through a currently documented API field | Prepare an exact fallback payload and require explicit authorization before the write. |
| Immutable field or unsupported mutation | Explain that a new campaign or Telnyx support ticket is required. |

### 4. Prepare corrections

Return exact diffs rather than general advice:

```json
{
  "field": "sample1",
  "current": "exact current value",
  "proposed": "exact proposed value",
  "evidence": "specific decline reason or validation finding",
  "execution_path": "Telnyx Agent CLI | Telnyx REST API fallback | support ticket"
}
```

Only propose changes supported by the diagnosis. Do not silently rewrite business facts, consent evidence, URLs, opt-in methods, or use cases.

### 5. Prefer an advertised Agent CLI edit; otherwise use the REST fallback

Inspect `telnyx-agent capabilities` and the current Agent CLI README first. If a
specific 10DLC edit command is advertised, use that command's current contract.
Do not use `setup-10dlc` for an update or resubmission.

If the Agent CLI does not expose the required edit, use the current
[Update Campaign API reference](https://developers.telnyx.com/api-reference/campaign/update-campaign)
and re-read it immediately before preparing the fallback write.

Only mutate fields that the current reference unambiguously identifies as
editable. If the narrative and generated request schema disagree, use the
narrower intersection: the presence of a field in a generated request schema
does not by itself prove that the field is mutable. Stop and use a support ticket
for the disputed field.

Before an update:

1. Retrieve the current campaign using the best advertised CLI command or, as a
   fallback, its Telnyx campaign UUID through the REST API.
2. Ask the Telnyx Support Agent to lint the exact proposed values.
3. Show the current and proposed values.
4. Obtain explicit authorization for the exact update.
5. Send only the authorized fields supported by the selected public contract.
6. Preserve the successful CLI or API response as the execution receipt.

If a required correction is not unambiguously editable, ask the Telnyx Support
Agent to create a support ticket. Do not claim that a resubmission, appeal, or
unsupported mutation occurred.

## Required machine-readable result

Return a structured artifact whenever the caller can preserve one:

```json
{
  "operation": "create | troubleshoot | update",
  "execution_surface": "support_agent_a2a | agent_cli | rest_api_fallback | human_support",
  "execution_state": "not_started | awaiting_confirmation | completed | failed | uncertain",
  "verified_facts": [],
  "actual_decline_reasons": [],
  "lint_blockers": [],
  "warnings": [],
  "proposed_command": null,
  "proposed_fallback_payload": null,
  "customer_action_required": [],
  "execution_allowed": false,
  "identifiers": {
    "brand_id": null,
    "tcr_brand_id": null,
    "campaign_id": null,
    "tcr_campaign_id": null,
    "reference_id": null,
    "a2a_task_id": null,
    "a2a_context_id": null
  },
  "next_step": ""
}
```

Do not omit the distinction between actual decline reasons, lint blockers, and warnings.

## Output language rules

- Use `draft`, `recommended`, `pending`, or `simulated` when that is the returned state.
- Use `created`, `updated`, `submitted`, or `resubmitted` only when a successful
  Agent CLI or REST response explicitly confirms the write.
- State which operation ran and which public surface performed it.
- Preserve exact IDs, statuses, URLs, field values, API errors, task IDs, and machine-readable artifacts.
- If the Telnyx Support Agent is unavailable, say so. Do not substitute model memory for an account-specific result.
- If live execution is uncertain, say `uncertain`; do not turn an ambiguous timeout into success or failure.

## Security and privacy

- Use the customer's API key only through `TELNYX_API_KEY` for Agent CLI or the
  bearer authorization header for A2A and REST.
- Never request or expose API keys, OTPs, PINs, signed approval tokens, or unrelated customer data in A2A messages.
- Do not use one customer's credential to inspect or modify another customer's resources.
- Log identifiers and non-secret receipts, not credentials.
- Follow the connection guide's polling, retry, and context contract.

## Public references

- [Telnyx Support Agent public agent card](https://api.telnyx.com/v2/support_agent/support/a2a/.well-known/agent-card.json)
- [Telnyx Agent CLI](https://github.com/team-telnyx/ai/tree/main/cli)
- [Agent CLI `setup-10dlc` implementation](https://github.com/team-telnyx/ai/blob/main/cli/src/commands/setup-10dlc.ts)
- REST fallback: [Qualify By Usecase API](https://developers.telnyx.com/api-reference/campaign/qualify-by-usecase)
- REST fallback: [Submit Campaign API](https://developers.telnyx.com/api-reference/campaign/submit-campaign)
- REST fallback: [Get Campaign API](https://developers.telnyx.com/api-reference/campaign/get-campaign)
- REST fallback: [Get Campaign Operation Status API](https://developers.telnyx.com/api-reference/campaign/get-campaign-operation-status)
- REST fallback: [Update Campaign API](https://developers.telnyx.com/api-reference/campaign/update-campaign)
