> ## Documentation Index
> Fetch the complete documentation index at: https://developers.telnyx.com/llms.txt
> Use this file to discover all available pages before exploring further.

# 10DLC Troubleshooting Guide

> Diagnose and resolve common 10DLC brand registration, campaign approval, phone number assignment, and messaging delivery issues.

This guide covers the most common 10DLC failures across brand registration, campaign approval, phone number assignment, and message delivery — with specific error codes, root causes, and fixes.

<Info>
  **Quick links:** [Brand issues](#brand-registration-failures) · [Campaign issues](#campaign-rejection-reasons) · [Number assignment issues](#phone-number-assignment-failures) · [Delivery issues](#message-delivery-failures) · [Carrier-specific issues](#carrier-specific-issues)
</Info>

***

## Brand registration failures

Brand registration fails when TCR cannot verify your business identity. The `identityStatus` field on your brand object indicates the result.

| Status            | Meaning                                 |
| ----------------- | --------------------------------------- |
| `VERIFIED`        | Brand identity confirmed                |
| `UNVERIFIED`      | Verification failed — action required   |
| `VETTED_VERIFIED` | External vetting completed successfully |
| `SELF_DECLARED`   | Sole proprietor — limited verification  |

### Common brand failures and fixes

<AccordionGroup>
  <Accordion title="EIN mismatch — company name doesn't match IRS records">
    **Error:** Brand identity verification failed — company name mismatch.

    **Root cause:** The `companyName` you submitted doesn't match what the IRS has on file for that EIN.

    **Fix:**

    1. Look up your exact legal name on the [IRS Tax Exempt Organization Search](https://apps.irs.gov/app/eos/) or your incorporation documents
    2. Update your brand with the exact legal name (including suffixes like "Inc.", "LLC")
    3. Re-submit for vetting

    ```bash curl theme={null}
    curl -X PATCH https://api.telnyx.com/v2/10dlc/brand/{brandId} \
      -H "Authorization: Bearer $TELNYX_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{"companyName": "Exact Legal Name Inc."}'
    ```
  </Accordion>

  <Accordion title="Address validation failure">
    **Error:** Brand address could not be verified.

    **Root cause:** The address doesn't match USPS records, or uses an incomplete format (e.g., missing suite number).

    **Fix:**

    1. Verify your address via [USPS Address Lookup](https://tools.usps.com/zip-code-lookup.htm)
    2. Use the exact USPS-standardized format
    3. Include suite/unit numbers if applicable
    4. Update the brand and re-submit

    <Warning>
      PO Boxes are generally not accepted. Use a physical business address.
    </Warning>
  </Accordion>

  <Accordion title="Website URL unreachable or doesn't match">
    **Error:** Brand website could not be verified.

    **Root cause:** TCR checks that the website is live and relates to the registered business. Common issues:

    * Website is down or returns errors
    * URL redirects to a different domain
    * Website content doesn't match the business name

    **Fix:**

    1. Ensure your website is live and loads without errors
    2. Use the root domain (e.g., `https://example.com`, not a deep link)
    3. Verify the website clearly identifies your business name
    4. Don't use placeholder/under-construction pages
  </Accordion>

  <Accordion title="Duplicate brand — already registered">
    **Error:** A brand with this EIN already exists.

    **Root cause:** Your business was already registered with TCR, either by you or another Telnyx account (or through another CSP).

    **Fix:**

    1. Check your existing brands: `GET /v2/10dlc/brand`
    2. If registered under another account, contact [Telnyx support](https://support.telnyx.com) to transfer ownership
    3. If registered through another CSP, you can still create campaigns through Telnyx as a secondary CSP
  </Accordion>

  <Accordion title="Duplicate vetting, already submitted">
    **Error:** `400` / code `10012`. The detail message reads "An external vetting for evpId 'X' and vettingClass 'Y' already exists for this brand" or "is already being processed for this brand."

    **Root cause:** A successful vetting for the same `(evpId, vettingClass)` exists within the last 180 days, or one is currently being processed.

    **Fix:**

    1. Retrieve existing vettings: `GET /v2/10dlc/brand/{brandId}/externalVetting`
    2. To order a different vetting, use a different `vettingClass` (for example `ENHANCED` instead of `STANDARD`) or a different `evpId`
    3. Failed vettings are excluded from this check, so you can retry immediately after a real failure
    4. Successful vettings expire after 6 to 12 months; once expired (TCR `EXPIRED` status), re-submission is allowed
  </Accordion>

  <Accordion title="Low vetting score">
    **Error:** Brand vetting score too low for desired throughput.

    **Root cause:** The third-party vetting partner (Campaign Verify) scored your brand below the threshold for your desired messaging volume.

    **Fix:**

    1. Review your brand profile for accuracy — incomplete or inconsistent data lowers scores
    2. Ensure your website, social media, and public records align with your brand information
    3. Request a re-vet after updating information (each vetting attempt has a fee)
    4. See [10DLC Rate Limits](/docs/messaging/10dlc/10dlc-rate-limits/index) for score-to-throughput mapping

    <Info>
      **Vetting score ranges:** 0–24 (low), 25–49 (medium-low), 50–74 (medium), 75–100 (high). Each tier unlocks higher throughput per carrier.
    </Info>
  </Accordion>

  <Accordion title="Sole proprietor OTP verification failure">
    **Error:** OTP verification timed out or failed.

    **Root cause:** The one-time password sent to your registered phone number wasn't confirmed in time, or the phone number can't receive SMS.

    **Fix:**

    1. Ensure the phone number on file can receive SMS
    2. Request a new OTP and complete verification within the time window
    3. Check that the phone number matches your identity documents
    4. See the [Sole Proprietor guide](/docs/messaging/10dlc/sole-proprietor) for detailed steps
  </Accordion>
</AccordionGroup>

### Check brand status via API

<CodeGroup>
  ```python Python theme={null}
  import telnyx

  telnyx.api_key = "YOUR_API_KEY"

  brand = telnyx.TenDlcBrand.retrieve("BRAND_ID")
  print(f"Status: {brand.identityStatus}")
  print(f"Entity Type: {brand.entityType}")

  if brand.identityStatus == "UNVERIFIED":
      print("⚠ Brand verification failed. Check rejection reason and update brand info.")
  ```

  ```javascript Node theme={null}
  const telnyx = require("telnyx")("YOUR_API_KEY");

  const brand = await telnyx.tenDlcBrands.retrieve("BRAND_ID");
  console.log(`Status: ${brand.data.identityStatus}`);

  if (brand.data.identityStatus === "UNVERIFIED") {
    console.log("⚠ Brand verification failed. Check rejection reason and update brand info.");
  }
  ```

  ```bash curl theme={null}
  curl -s https://api.telnyx.com/v2/10dlc/brand/BRAND_ID \
    -H "Authorization: Bearer $TELNYX_API_KEY" | python3 -m json.tool
  ```
</CodeGroup>

***

## Campaign rejection reasons

Campaign rejections happen during carrier review. The rejection reason is delivered via [10DLC Event Notifications](/docs/messaging/10dlc/event-notifications/index) webhooks.

| Rejection Reason                  | Common Cause                                                      | Fix                                                                                                               |
| --------------------------------- | ----------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------- |
| **Samples don't match use case**  | Sample messages describe a different use case than declared       | Rewrite samples to match the exact declared use case                                                              |
| **Missing opt-out language**      | No STOP/unsubscribe instructions in samples                       | Add "Reply STOP to unsubscribe" to every sample                                                                   |
| **Inadequate opt-in description** | Opt-in workflow is vague or missing                               | Describe the exact opt-in mechanism (web form URL, keyword, etc.)                                                 |
| **Prohibited content**            | SHAFT content (sex, hate, alcohol, firearms, tobacco) or cannabis | Remove prohibited content or apply for special use case approval                                                  |
| **Brand not vetted**              | Campaign submitted before brand vetting completed                 | Complete [brand vetting](/docs/messaging/10dlc/brand-registration/index#step-3-submit-for-external-vetting) first |
| **Duplicate campaign**            | Similar campaign already registered for this brand                | Use the existing campaign or differentiate the use case                                                           |
| **Insufficient sample messages**  | Not enough variety in sample messages                             | Provide 2–5 diverse samples showing different message types                                                       |

### Writing samples that pass review

<Steps>
  <Step title="Match your declared use case exactly">
    If you registered as "Customer Care," every sample should be a customer service message:

    > ✅ "Hi Jane, your support ticket #4521 has been resolved. Reply HELP for assistance or STOP to opt out."

    > ❌ "Flash sale! 50% off today only!" (this is marketing, not customer care)
  </Step>

  <Step title="Include opt-out in every sample">
    Every sample message should include opt-out instructions:

    > ✅ "Your order #1234 has shipped. Track: [https://example.com/track](https://example.com/track). Reply STOP to unsubscribe."
  </Step>

  <Step title="Use realistic content — no placeholders">
    Carriers reject generic or placeholder text:

    > ❌ "This is a test message"
    >
    > ❌ "Hello {name}, this is {company}"

    > ✅ "Hi Sarah, your appointment at Downtown Clinic is confirmed for March 5 at 2:00 PM. Reply C to confirm or R to reschedule. Reply STOP to opt out."
  </Step>

  <Step title="Show variety in your samples">
    Provide 2–5 samples that demonstrate different message types within your use case:

    * Confirmation messages
    * Follow-up messages
    * Status update messages
    * Opt-in confirmation messages
  </Step>
</Steps>

### Resubmitting after rejection

You cannot edit a rejected campaign. Create a new one with corrected information:

```python Python theme={null}
import telnyx

telnyx.api_key = "YOUR_API_KEY"

# Create a new campaign with corrected samples
campaign = telnyx.TenDlcCampaign.create(
    brandId="BRAND_ID",
    usecase="CUSTOMER_CARE",
    description="Customer support notifications for order updates and ticket resolution",
    sample1="Hi Jane, your support ticket #4521 has been resolved. Let us know if you need anything else. Reply STOP to opt out.",
    sample2="Your order #8876 is out for delivery and should arrive by 3 PM today. Reply STOP to unsubscribe.",
    messageFlow="Customers opt in via checkbox on our website checkout page at https://example.com/checkout. They can opt out at any time by replying STOP.",
    helpMessage="Reply HELP for support options or visit https://example.com/help",
    optoutMessage="You have been unsubscribed and will no longer receive messages from us."
)

print(f"New campaign ID: {campaign.id}")
print(f"Status: {campaign.campaignStatus}")
```

<Warning>
  Each campaign submission incurs a TCR registration fee ($15 standard / $4 low-volume). Review samples carefully before submitting to avoid repeated fees.
</Warning>

***

## Phone number assignment failures

After campaign approval, you must assign phone numbers to the campaign. Failures typically involve number eligibility or carrier registration issues.

<AccordionGroup>
  <Accordion title="Number not eligible for 10DLC">
    **Error:** Phone number is not eligible for 10DLC campaign assignment.

    **Root cause:** The number may be:

    * A toll-free number (use [toll-free verification](/docs/messaging/toll-free-verification) instead)
    * A short code
    * Not provisioned for messaging
    * Already assigned to another campaign

    **Fix:**

    1. Verify the number type: `GET /v2/phone_numbers/{id}`
    2. Ensure it's a standard long code (10-digit US number)
    3. Enable messaging on the number if not already configured
    4. Unassign from any existing campaign before reassigning
  </Accordion>

  <Accordion title="AT&T registration timeout">
    **Error:** Phone number registration with AT\&T timed out.

    **Root cause:** AT\&T's 10DLC registration system can be slow, especially during high-volume periods. Registration can take up to 7 business days.

    **Fix:**

    1. Wait 7 business days before escalating
    2. Check the number's registration status via webhooks or API
    3. If still pending after 7 days, [contact Telnyx support](https://support.telnyx.com)

    <Info>
      AT\&T processes 10DLC number registrations in batches. Delays of 3–5 business days are normal.
    </Info>
  </Accordion>

  <Accordion title="T-Mobile number rejection">
    **Error:** T-Mobile rejected the phone number registration.

    **Root cause:** T-Mobile applies additional scrutiny to numbers with low-score brands or campaigns flagged for review.

    **Fix:**

    1. Ensure your brand vetting score is sufficient
    2. Verify the campaign isn't flagged or suspended
    3. Try reassigning the number after the campaign is fully approved
    4. Contact [Telnyx support](https://support.telnyx.com) if the issue persists
  </Accordion>

  <Accordion title="Bulk assignment partial failure">
    **Error:** Some numbers in a bulk assignment request failed while others succeeded.

    **Root cause:** Mixed eligibility in the batch — some numbers may already be assigned or not eligible.

    **Fix:** Check results individually and retry only the failed numbers:

    ```python Python theme={null}
    import telnyx
    import time

    telnyx.api_key = "YOUR_API_KEY"

    failed_numbers = ["+12125551234", "+12125555678"]  # Numbers that failed

    for number in failed_numbers:
        try:
            # Check current assignment status
            resp = telnyx.PhoneNumber.retrieve(number)
            print(f"{number}: messaging_profile={resp.messaging_profile_id}")
            
            # Retry assignment
            telnyx.TenDlcPhoneNumberCampaign.create(
                phoneNumber=number,
                campaignId="CAMPAIGN_ID"
            )
            print(f"✓ {number} assigned successfully")
        except Exception as e:
            print(f"✗ {number}: {e}")
        time.sleep(1)
    ```
  </Accordion>
</AccordionGroup>

***

## Message delivery failures

Even with approved campaigns and assigned numbers, messages can still fail. These are the most common 10DLC-specific delivery errors.

| Error Code | Description                     | Fix                                                                                         |
| ---------- | ------------------------------- | ------------------------------------------------------------------------------------------- |
| `40300`    | Number not registered for 10DLC | Assign the sending number to an approved campaign                                           |
| `40301`    | Campaign suspended              | Check campaign status; contact support if unexpected                                        |
| `40302`    | Brand suspended                 | Review brand status and resolve compliance issues                                           |
| `40310`    | Rate limit exceeded             | Reduce sending rate; see [10DLC Rate Limits](/docs/messaging/10dlc/10dlc-rate-limits/index) |
| `40311`    | Daily message limit reached     | Wait for daily reset or request higher throughput via vetting                               |
| `40320`    | Content flagged by carrier      | Review message content for SHAFT violations                                                 |
| `40321`    | URL blocked by carrier          | Remove or replace flagged URLs; use branded short links                                     |

### Debugging delivery issues

<CodeGroup>
  ```python Python theme={null}
  import telnyx
  import json

  telnyx.api_key = "YOUR_API_KEY"

  # Check message detail record for error info
  mdr = telnyx.MessageDetailRecord.list(
      direction="outbound",
      phone_number="+12125551234",
      start_date="2026-03-01T00:00:00Z",
      end_date="2026-03-02T00:00:00Z"
  )

  for record in mdr.data:
      if record.status != "delivered":
          print(f"Message {record.id}")
          print(f"  Status: {record.status}")
          print(f"  Error: {record.errors}")
          print(f"  To: {record.to}")
          print(f"  Sent at: {record.created_at}")
  ```

  ```javascript Node theme={null}
  const telnyx = require("telnyx")("YOUR_API_KEY");

  const mdrs = await telnyx.messageDetailRecords.list({
    direction: "outbound",
    phone_number: "+12125551234",
    start_date: "2026-03-01T00:00:00Z",
    end_date: "2026-03-02T00:00:00Z",
  });

  for (const record of mdrs.data) {
    if (record.status !== "delivered") {
      console.log(`Message ${record.id}`);
      console.log(`  Status: ${record.status}`);
      console.log(`  Error: ${JSON.stringify(record.errors)}`);
    }
  }
  ```

  ```bash curl theme={null}
  curl -s "https://api.telnyx.com/v2/message_detail_records?direction=outbound&phone_number=%2B12125551234&start_date=2026-03-01T00:00:00Z&end_date=2026-03-02T00:00:00Z" \
    -H "Authorization: Bearer $TELNYX_API_KEY" | python3 -m json.tool
  ```
</CodeGroup>

***

## Carrier-specific issues

Each major US carrier handles 10DLC differently. Here are carrier-specific behaviors to be aware of:

### AT\&T

| Issue                  | Details                                                          |
| ---------------------- | ---------------------------------------------------------------- |
| **Registration delay** | 3–7 business days for number registration                        |
| **Content filtering**  | Aggressive URL filtering; avoid URL shorteners (bit.ly, tinyurl) |
| **Rate limits**        | Lowest per-campaign limits; vetting score has largest impact     |
| **Suspension**         | Will suspend campaigns with spam complaints without warning      |

### T-Mobile

| Issue                   | Details                                                     |
| ----------------------- | ----------------------------------------------------------- |
| **Content filtering**   | Blocks messages with prohibited content patterns            |
| **Number reassignment** | Requires 24h cooldown when moving numbers between campaigns |
| **Daily limits**        | Enforces strict daily per-number limits                     |
| **Opt-out enforcement** | Automatically blocks messages to numbers that texted STOP   |

### Verizon

| Issue            | Details                                       |
| ---------------- | --------------------------------------------- |
| **Registration** | Generally fastest registration processing     |
| **Content**      | Less aggressive filtering than AT\&T/T-Mobile |
| **Rate limits**  | More generous throughput at all vetting tiers |

***

## Diagnostic checklist

Use this checklist when troubleshooting any 10DLC issue:

<Steps>
  <Step title="Verify brand status">
    `GET /v2/10dlc/brand/{brandId}` — confirm `identityStatus` is `VERIFIED` or `VETTED_VERIFIED`
  </Step>

  <Step title="Verify campaign status">
    `GET /v2/10dlc/campaign/{campaignId}` — confirm `campaignStatus` is `ACTIVE`
  </Step>

  <Step title="Verify number assignment">
    `GET /v2/10dlc/phoneNumberCampaign?phoneNumber={number}` — confirm the sending number is assigned to the active campaign
  </Step>

  <Step title="Check event notifications">
    Review [10DLC webhooks](/docs/messaging/10dlc/event-notifications/index) for rejection, suspension, or status change events
  </Step>

  <Step title="Review message detail records">
    Check [MDRs](/docs/messaging/messages/message-detail-records/index) for specific error codes on failed messages
  </Step>

  <Step title="Check rate limits">
    Compare your sending rate against your [campaign throughput limits](/docs/messaging/10dlc/10dlc-rate-limits/index). Vetting score determines your ceiling.
  </Step>
</Steps>

***

## Get help

If you've followed this guide and still have issues:

<CardGroup cols={2}>
  <Card title="Support Ticket" icon="ticket" href="https://support.telnyx.com">
    Open a support ticket with your brand ID, campaign ID, and error details.
  </Card>

  <Card title="10DLC Status" icon="signal" href="https://portal.telnyx.com/#/app/messaging/10dlc">
    Check brand, campaign, and number status in Mission Control.
  </Card>

  <Card title="Event Notifications" icon="bell" href="/docs/messaging/10dlc/event-notifications/index">
    Set up webhooks to catch status changes in real time.
  </Card>

  <Card title="Rate Limits" icon="gauge" href="/docs/messaging/10dlc/10dlc-rate-limits/index">
    Review throughput limits by vetting score tier.
  </Card>
</CardGroup>
