US 10DLC API Installation

A quick start to install a US 10 DLC number

10DLC is a local 10-digit phone number that requires Brand & Use Case registration and supports throughput levels suitable for A2P SMS campaigns. 10DLC is sanctioned by mobile carriers for A2P messaging and is intended to provide a reliable user experience, better deliverability, and higher messaging speed. To find out more about 10DLC see the following page

To setup a new channel to send SMS messages using a United states 10 digit long code number the following steps are required

Some of the following requests will lead to additional workspace charges. Ensure you understand the costs before proceeding

API Access

The following API requests can only be made using a valid access key and attached to an access role with the an access policy that at least specifies the permissions to the resources outlined in each section below.

Find an available number

If you do not already have a US 10DLC number available in your workspace you can find one to purchase .You can filter by country, prefix, number type and number capabilities.

Example

The following example will return the first available US local number required for use with 10DLC registration.

curl --location 'https://api.bird.com/workspaces/<your-workspace-id>/numbers-available?limit=1&country=US&type=local' \
--header 'Accept: application/json' \
--header 'Authorization: AccessKey <your-access-key>'

Purchase a number

Once you have found an available number you can purchase this by providing the number (in E.1624 format) and the country (using a two digit ISO code).

A successful request to this endpoint will start a recurring monthly subscription based on the monthly cost of the number

The following example will purchase the number if it still available and you have sufficient balance in your workspace wallet. Provide number in E.1624 format and country in 2 digit ISO code (e.g. US)

curl --location 'https://api.bird.com/workspaces/<your-workspace-id>/numbers' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'Authorization: AccessKey <your-access-key>' \
--data '{
  "numbers": [
    {
      "number": "",
      "country": ""
    }
  ]
}'

(Optional) Set up 10DLC webhook subscriptions

You can set up a Web Hook subscription to be notified of any brand or campaign event. Brand and camping creation work in sync, and subscribing to all related events will automate the 10DLC registration process.

Brand Subscriptions

The Following example will Create a subscrscrition listing to all Brand Related events

curl --location 'https://api.bird.com/organizations/<your-organization-id>/workspaces/<your-workspace-id>/webhook-subscriptions' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'Authorization: AccessKey <your-access-key>' \
--data '{
    "signingKey": "my-signing-key",
    "eventFilters": [

    ],
    "event": "10dlc.brand",
    "service": "numbers",
    "url": "<your-webhook-url>"
    }'

Campaign Subscription

The Following example will Create a subscription listing to all Brand Related events

curl --location 'https://api.bird.com/organizations/<your-organization-id>/workspaces/<your-workspace-id>/webhook-subscriptions' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'Authorization: AccessKey <your-access-key>' \
--data '{
    "signingKey": "my-signing-key",
    "eventFilters": [

    ],
    "event": "10dlc.campaign",
    "service": "numbers",
    "url": "<your-webhook-url>"
    }'

Register a new brand with the campaign registry

A-Sync : this will start a background process that may require some time to complete. A Get call may be required to to retrieve the final result .

Before you can use a US 10DLC number to send SMS messages, you must be register a brand and campaign with an external registry called the campaign registry.

After creating a brand, this will be submitted for approval by the campaign registry. The brand must be approved before you can register a campaign with the campaign registry. Brand registration may take some time.

You can find the full list of brand management endpoints here

A successful request to this endpoint will mean you are charged a brand registration fee. If you later need to update or resubmit your brand there may be additional fees.

The following example will create a new brand that will be submitted for registration with the campaign registry.

curl --location 'https://api.bird.com/workspaces/<your-workspace-id>/tcr-brands' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'Authorization: AccessKey <your-access-key>' \
--data '{
  "entityType": "",
  "firstName": "",
  "lastName": "",
  "displayName": "",
  "companyName": "",
  "ein": "",
  "einIssuingCountry": "",
  "phone": "",
  "street": "",
  "city": "",
  "state": "",
  "postalCode": "",
  "country": "",
  "email": "",
  "stockSymbol": "",
  "stockExchange": "",
  "website": "",
  "vertical": "",
  "altBusinessId": "",
  "altBusinessIdType": ""
}

(Optional) Submit brand for external vetting

A-Sync : this will start a background process that may require some time to complete. A Get call may be required to to retrieve the final result .

The final result of If your brand is not being accepted or your company is not part of the Russell 3000 stock index you can also request additional vetting. For brands that are not part of the Russell 3000 stock index this can provide access to higher messaging throughputs (depending on your vetting score)

A successful request to this endpoint will mean you are charged a brand vetting fee.

The following example will create a new brand vetting request that will be submitted for registration with the campaign registry. You must have previously created a brand

curl --location 'https://api.bird.com/workspaces/<your-workspace-id>/tcr-brands/<your-brand-id>/vettings' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'Authorization: AccessKey <your-access-key>' \
--data '{
  "class": "STANDARD",
  "vettingProviderId": "AEGIS"
}

Register a new campaign with the campaign registry

To reduce the likelihood of rejection, ensure you are familiar with 10dlc registration examples and best practices. Specifically

  • Check this article for tips on how to write an effective Campaign description

  • Check this article on how to write an effective messageFlow

Most 10DLC rejections are caused by unclear or incomplete description and/or messageFlow

A-Sync : this will start a background process that may require some time to complete. A Get call may be required to to retrieve the final result .

Once your brand status is approved you can then create your first campaign. Brands can have multiple campaigns. A campaign describes what types of messages you will send from your SMS channel.

After creating a campaign, this will be submitted for approval by the campaign registry. The campaign must be approved before you can associate this with an SMS channel. Campaign registration can take 1-2 weeks to be approved.

You can find the full list of campaign management endpoints here

A successful request to this endpoint will mean you are charged a campaign registration fee and a three month minimum commitment fee. If you later need to update or resubmit your brand there may be additional fees.

The following example will create a new campaign that will be submitted for registration with the campaign registry. Your associated brand must be approved

curl --location 'https://api.bird.com/workspaces/<your-workspace-id>/tcr-brands/<your-brand-id>/campaigns' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'Authorization: AccessKey <your-access-key>' \
--data '{
  "name": "",
  "usecase": "",
  "subUsecases": [
    ""
  ],
  "description": "",
  "embeddedLink": ,
  "embeddedPhone": ,
  "numberPool": ,
  "ageGated": ,
  "directLending": ,
  "subscriberOptin": ,
  "subscriberOptout": ,
  "subscriberHelp": ,
  "samples": [
    ""
  ],
  "messageFlow": "",
  "helpMessage": "",
  "helpKeywords": "",
  "optoutKeywords": "",
  "optinKeywords": "",
  "optinMessage": "",
  "optoutMessage": "",
  "termsAndConditions": true
}'

Same as done before, you can create a workspace subscription to listen to Channel Status changes

Channel Updates Subscription

The example below will create a workspace-wide subscription tracking all updates regarding your channels you can use to track channels' status changes

curl --location 'https://api.bird.com/organizations/<your-organization-id>/workspaces/<your-workspace-id>/webhook-subscriptions' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'Authorization: AccessKey <your-access-key>' \
--data '{
  "service": "channels",
  "event": "channel.updated",
  "url": "myURL.com",
  "signingKey": "mysecretkey",
  "eventFilters": [
  ]
}'

Install a channel connector

A-Sync : this will start a background process that may require some time to complete. A Get call may be required to to retrieve the final result .

The following example will create a new SMS connector with an approved 10DLC campaign and US local number:

curl --location 'https://api.bird.com/workspaces/<your-workspace-id>/connectors' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'Authorization: AccessKey <your-access-key>' \
--data '{
    "connectorTemplateRef": "sms-messagebird:1",
    "name": "SMS channel",
    "arguments": {
        "phoneNumberId": "",
        "useCaseId": "",
        "channelMessageType": "",
    },
    "channelConversationalStatusEnabled": true
}

Get your channel id

Once you have created your SMS connector, this will create an SMS channel. You can then get your channel ID to before setting up channel webhooks

If you are listening to channels events the channelId will be returned with the first channel updated event

The following example will get the connector you have created in the previous step. Parse the channel.channelId to get the id of your new SMS channel

curl --location 'https://api.bird.com/workspaces/<your-workspace-id>/connectors/<your-connector-id>' \
--header 'Accept: application/json' \
--header 'Authorization: AccessKey <your-access-key>'

Setup channel message webhooks

Once your channel has been installed you will then need to setup a webhook subscription to receive status updates and inbound messages

The following request example will create a new SMS subscription for inbound and outbound messages

Inbound messages

curl --location 'https://api.bird.com/organizations/<your-organization-id>/workspaces/<your-workspace-id>/webhook-subscriptions' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'Authorization: AccessKey <your-access-key>' \
--data '{
    "signingKey": "my-signing-key",
    "eventFilters": [
        {
            "key": "channelId",
            "value": "<your-channel-id>"
        }
    ],
    "event": "sms.inbound",
    "service": "channels",
    "url": "<your-webhook-url>"
}'

Outbound messages

curl --location 'https://api.bird.com/organizations/<your-organization-id>/workspaces/<your-workspace-id>/webhook-subscriptions' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'Authorization: AccessKey <your-access-key>' \
--data '{
    "signingKey": "my-signing-key",
    "eventFilters": [
        {
            "key": "channelId",
            "value": "<your-channel-id>"
        }
    ],
    "event": "sms.outbound",
    "service": "channels",
    "url": "<your-webhook-url>"
}'

Confirm a 10DLC Channels Readiness to send SMS traffic

A-Sync : this will start a background process that may require some time to complete. A Get call may be required to retrieve the final result

10DLC numbers can only send traffic to the USA when linked to a campaign. Number Campaign link is an A-sync process requiring confirmations from multiple carriers.

The bird will only consider a number linked if all major USA carriers acknowledge the links. Delays in carrier acknowledgment can vary between 15 minutes to several hours and are usually longer around peak linking hours (afternoon/evening USA Pacific time)

Based on whether you have subscribed or not to channel events, you can determine the readiness of a given channel in 2 ways

Option 1: you are subscribed to channel updates

if you have a "channel.updated" event subscription, each change in a channel status will trigger an event. You can associate those events to the number you have used to install the channel by referring to "identifier" field. A channel ready to send SMS will have "status": "active".

{
  "service": "channels",
  "event": "channel.created",
  "payload": {
    "id": "f5d391a8-29b6-5092-940c-9a1cd7d06f30",
    "status": "active",
    "platformId": "sms-messagebird",
    "name": "SMS - 🇺🇸 +19802683122",
    "connectorId": "c8a93146-68e5-4e60-a77c-659877768bec",
    "identifier": "+19802683122",
    "preferences": {
      "disableProfileFetching": false,
      "explicitMarketingOptOut": false,
      "trackAdInitiatedThreads": false
    },
    "capabilities": {
      "messaging": {
        "displayName": "Messaging capabilities",
        "status": "active",
        "name": "",
        "expiresAt": "1970-01-01T00:00:00Z",
        "version": 0,
        "createdAt": "0001-01-01T00:00:00Z",
        "updatedAt": "0001-01-01T00:00:00Z",
        "outgoing": {
          "displayName": "Capability to send outgoing messages",
          "status": "active",
          "name": "",
          "version": 0,
          "createdAt": "1970-01-01T00:00:00Z",
          "updatedAt": "1970-01-01T00:00:00Z",
          "mms": {
            "displayName": "Capability to send outgoing mms messages",
            "status": "inactive",
            "name": "",
            "version": 0,
            "createdAt": "1970-01-01T00:00:00Z",
            "updatedAt": "1970-01-01T00:00:00Z"
          }
        },
        "incoming": {
          "displayName": "Capability to receive messages",
          "status": "active",
          "name": "",
          "version": 0,
          "createdAt": "1970-01-01T00:00:00Z",
          "updatedAt": "1970-01-01T00:00:00Z"
        }
      }
    },
    "useCaseId": "b43d79ab-3cbb-4a4a-9461-5da533f0cb18",
    "useCaseType": "marketing",
    "createdAt": "2024-09-20T12:08:57.098Z",
    "updatedAt": "2024-09-20T12:08:57.098Z"
  }
}

Option 2: you are NOT subscribed to channel updates

if so you can query the GET connector status endpoint and wait for the "useCaseStatus" to turn to "ok"

The channel cannot terminate SMS to the USA

This could happen if the number linked to its campaigns is not acknowledged or the 10DLC registration experiences issues. In this case, the "useCaseStatus" 's value will not be "ok"

"name": "useCaseStatus",
                "displayName": "UseCase Status",
                "assertions": [
                    {
                        "name": "brand",
                        "displayName": "",
                        "description": "",
                        "status": "ok"
                    },
                    {
                        "name": "campaign",
                        "displayName": "",
                        "description": "",
                        "status": "ok"
                    },
                    {
                        "name": "checks whether number is linked to campaign",
                        "displayName": "",
                        "description": "",
                        "status": "warning",
                        "message": "Number status is INACTIVE"
                    }
                ],
                "status": "warning"

The channel can terminate messages to the USA

In this case "useCaseStatus" will be "ok"

"name": "useCaseStatus",
                "displayName": "UseCase Status",
                "assertions": [
                    {
                        "name": "brand",
                        "displayName": "",
                        "description": "",
                        "status": "ok"
                    },
                    {
                        "name": "campaign",
                        "displayName": "",
                        "description": "",
                        "status": "ok"
                    },
                    {
                        "name": "checks whether number is linked to campaign",
                        "displayName": "",
                        "description": "",
                        "status": "ok"
                    }
                ],
                "status": "ok"
```

Last updated