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.

List Organization Numbers Stock Items

GET/organizations/{organizationId}/numbers-stock-items
Authorization
Path parameters
organizationId*string
Query parameters
Response

OK

Body
results*array of NumberStockItem (object)
nextPageTokenstring

The token that can be passed as pageToken in URL to retrieve the next set of results. If missing, no more results to display.

Request
const response = await fetch('/organizations/{organizationId}/numbers-stock-items', {
    method: 'GET',
    headers: {
      "Authorization": "Bearer jwt"
    },
});
const data = await response.json();
Response
{
  "results": [
    {
      "id": "123e4567-e89b-12d3-a456-426614174000",
      "countryCode": "text",
      "type": "local",
      "numberString": "text",
      "capabilities": {
        "voice": {
          "inbound": false,
          "outbound": false
        },
        "sms": {
          "inbound": false,
          "outbound": false
        },
        "mms": {
          "inbound": false,
          "outbound": false
        }
      },
      "monthlyPrice": {
        "currencyCode": "EUR"
      }
    }
  ],
  "nextPageToken": "text"
}

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 it by providing the number (using the unique identifier provided by the endpoint above).

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

Create Workspace Long Code Numbers

Assigns Long Code Numbers to the current workspace, charging the wallet for their subscription price. When creating LCNs as a User, all specified Number Stock Items should be reserved.

POST/workspaces/{workspaceId}/numbers-long-code
Authorization
Path parameters
workspaceId*string
Body
numberStockItemIds*array of string (uuid)
Response

Created

Body
results*array of WorkspaceLongCodeNumber (object)
Request
const response = await fetch('/workspaces/{workspaceId}/numbers-long-code', {
    method: 'POST',
    headers: {
      "Authorization": "Bearer jwt",
      "Content-Type": "application/json"
    },
    body: JSON.stringify({
      "numberStockItemIds": [
        "123e4567-e89b-12d3-a456-426614174000"
      ]
    }),
});
const data = await response.json();
Response
{
  "results": [
    {
      "id": "123e4567-e89b-12d3-a456-426614174000",
      "endpointId": "123e4567-e89b-12d3-a456-426614174000",
      "numberString": "text",
      "countryCode": "text",
      "type": "local",
      "capabilities": {
        "voice": {
          "inbound": false,
          "outbound": false
        },
        "sms": {
          "inbound": false,
          "outbound": false
        },
        "mms": {
          "inbound": false,
          "outbound": false
        }
      },
      "createdAt": "2024-10-22T10:10:58.936Z",
      "updatedAt": "2024-10-22T10:10:58.936Z",
      "order": {
        "countryCode": "text",
        "type": "local",
        "capabilities": [
          "voice"
        ],
        "prefix": "text",
        "status": "draft",
        "createdAt": "2024-10-22T10:10:58.936Z",
        "updatedAt": "2024-10-22T10:10:58.936Z"
      },
      "deprovisionAt": "2024-10-22T10:10:58.936Z",
      "endpoint": {
        "id": "123e4567-e89b-12d3-a456-426614174000",
        "type": "long-code-number",
        "instanceId": "123e4567-e89b-12d3-a456-426614174000",
        "name": "text",
        "capabilities": [
          {
            "name": "sms",
            "inbound": {
              "status": "active",
              "issues": [
                "subscription-is-not-active"
              ]
            },
            "outbound": {
              "status": "active",
              "destinationStatuses": {
                "active": 0,
                "inactive": 0,
                "available": 0,
                "unavailable": 0
              },
              "supportsDestinations": false,
              "issues": [
                "subscription-is-not-active"
              ]
            }
          }
        ],
        "dependencies": [
          {
            "type": "connector",
            "connectorId": "123e4567-e89b-12d3-a456-426614174000",
            "connectorTemplateRef": "text",
            "capabilities": [
              "voice"
            ]
          }
        ],
        "issues": [
          "subscription-is-not-active"
        ],
        "provisioningStatus": "provisioned",
        "createdAt": "2024-10-22T10:10:58.936Z",
        "updatedAt": "2024-10-22T10:10:58.936Z"
      }
    }
  ]
}

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.

Create a brand in a workspace

POST/workspaces/{workspaceId}/tcr-brands
Authorization
Path parameters
workspaceId*string
Body
entityType*BrandEntityType (enum)

Legal entity type. It can't be updated when the brand is approved.

Example: "PRIVATE_PROFIT"
PRIVATE_PROFITPUBLIC_PROFITNON_PROFITGOVERNMENT
firstNamestring

First or given name. Applicable to entity type.

Example: "John"
lastNamestring

Last or Surname. Applicable to entity type.

Example: "Doe"
displayName*string

Display or marketing name your brand.

Example: "ABC Mobile"
companyName*string

Legal company name. This should match the legal company name used to register your EIN/Tax ID.

Example: "ABC Inc."
ein*string

Government assigned corporate tax ID. EIN is 9-digits in the U.S.

Example: "111111111"
einIssuingCountry*string

The 2 letter ISO country of registration submitted with your EIN / Tax ID registration.

Example: "US"
phone*string

Valid phone number in e.164 international format.

Example: "+12024567890"
street*string

Street number and name.

Example: "123 6th Ave"
city*string

City name

Example: "New York"
state*string

State. Must be a 2 letter state code for US states.

Example: "NY"
postalCode*string

Postal code. Must be a 5 digit zip code for the United States.

Example: "10001"
country*string

ISO 2 character country code.

Example: "US"
email*string

Valid email address of brand support contact.

Example: "johndoe@abc.com"
stockSymbolstring

Stock symbol. Required for entityType PUBLIC.

Example: "ABC"
stockExchangeBrandStockExchange (enum)

Stock exchange. Required for entityType PUBLIC.

Example: "NASDAQ"
NONENASDAQNYSEAMEXAMXASXB3BMEBSEFRAICEXJPXJSEKRXLONNSEOMXSEHKSGXSSESTOSWXSZSETSXTWSEVSEOTHER
website*string

Brand website URL.

Example: "https://example.com"
verticalstring

Vertical or industry segment of the brand.

Example: "RETAIL"
altBusinessIdstring

Alternate business identifier.

altBusinessIdTypeBrandAltBusinessIdType (enum)

Alternate business identifier type. Required if altBusinessId is provided.

NONEDUNSGIINLEI
Response

Brand successfully created

Body
idstring (uuid)

The ID of the number.

organizationIdstring (uuid)
createdAtstring (date-time)

Timestamp (UTC) when the brand was created.

updatedAtnullable string (date-time)

Timestamp (UTC) when the brand was last updated.

statusBrandStatus (enum)

Brand status

Example: "PENDING"
FAILEDPENDINGREJECTEDAPPROVEDDELETEDDRAFT
entityType*BrandEntityType (enum)

Legal entity type. It can't be updated when the brand is approved.

Example: "PRIVATE_PROFIT"
PRIVATE_PROFITPUBLIC_PROFITNON_PROFITGOVERNMENT
firstNamestring

First or given name. Applicable to entity type.

Example: "John"
lastNamestring

Last or Surname. Applicable to entity type.

Example: "Doe"
displayName*string

Display or marketing name your brand.

Example: "ABC Mobile"
companyName*string

Legal company name. This should match the legal company name used to register your EIN/Tax ID.

Example: "ABC Inc."
ein*string

Government assigned corporate tax ID. EIN is 9-digits in the U.S.

Example: "111111111"
einIssuingCountry*string

The 2 letter ISO country of registration submitted with your EIN / Tax ID registration.

Example: "US"
phone*string

Valid phone number in e.164 international format.

Example: "+12024567890"
street*string

Street number and name.

Example: "123 6th Ave"
city*string

City name

Example: "New York"
state*string

State. Must be a 2 letter state code for US states.

Example: "NY"
postalCode*string

Postal code. Must be a 5 digit zip code for the United States.

Example: "10001"
country*string

ISO 2 character country code.

Example: "US"
email*string

Valid email address of brand support contact.

Example: "johndoe@abc.com"
stockSymbolstring

Stock symbol.

Example: "ABC"
stockExchangeBrandStockExchange (enum)

Stock exchange. Required for entityType PUBLIC.

Example: "NASDAQ"
NONENASDAQNYSEAMEXAMXASXB3BMEBSEFRAICEXJPXJSEKRXLONNSEOMXSEHKSGXSSESTOSWXSZSETSXTWSEVSEOTHER
website*string

Brand website URL.

Example: "https://example.com"
verticalstring

Vertical or industry segment of the brand.

Example: "RETAIL"
altBusinessIdstring

Alternate business identifier.

altBusinessIdTypeBrandAltBusinessIdType (enum)

Alternate business identifier type. Required if altBusinessId is provided.

NONEDUNSGIINLEI
workspaceIdsnullable array of string (uuid)

Workspace IDs with access to the brand.

rejectionobject

Rejection details

Request
const response = await fetch('/workspaces/{workspaceId}/tcr-brands', {
    method: 'POST',
    headers: {
      "Authorization": "Bearer jwt",
      "Content-Type": "application/json"
    },
    body: JSON.stringify({
      "country": "US",
      "displayName": "ABC Mobile",
      "email": "johndoe@abc.com",
      "entityType": "PRIVATE_PROFIT",
      "phone": "+12024567890",
      "street": "123 6th Ave",
      "city": "New York",
      "state": "NY",
      "postalCode": "10001",
      "companyName": "ABC Inc.",
      "ein": "111111111",
      "einIssuingCountry": "US",
      "website": "https://example.com"
    }),
});
const data = await response.json();
Response
{
  "id": "123e4567-e89b-12d3-a456-426614174000",
  "organizationId": "123e4567-e89b-12d3-a456-426614174000",
  "createdAt": "2024-10-22T10:10:58.936Z",
  "updatedAt": "2024-10-22T10:10:58.936Z",
  "status": "PENDING",
  "entityType": "PRIVATE_PROFIT",
  "firstName": "John",
  "lastName": "Doe",
  "displayName": "ABC Mobile",
  "companyName": "ABC Inc.",
  "ein": "111111111",
  "einIssuingCountry": "US",
  "phone": "+12024567890",
  "street": "123 6th Ave",
  "city": "New York",
  "state": "NY",
  "postalCode": "10001",
  "country": "US",
  "email": "johndoe@abc.com",
  "stockSymbol": "ABC",
  "stockExchange": "NASDAQ",
  "website": "https://example.com",
  "vertical": "RETAIL",
  "altBusinessId": "text",
  "altBusinessIdType": "NONE",
  "workspaceIds": [
    "123e4567-e89b-12d3-a456-426614174000"
  ],
  "rejection": {
    "description": "text",
    "code": "text"
  }
}

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.

Create a brand vetting in a workspace. Brand vetting should be requested when the brand is not getting approved, or if the customer needs a higher throughput.

POST/workspaces/{workspaceId}/tcr-brands/{brandId}/vettings
Authorization
Path parameters
workspaceId*string
brandId*string
Body
class*BrandVettingClass (enum)

Identifies the vetting classification.

Example: "STANDARD"
STANDARD
vettingProviderIdstring

External vetting provider ID for the brand.

Response

Brand vetting successfully created

Body
id*string (uuid)

Unique ID that identifies a vetting transaction performed by a vetting provider.

brandId*string (uuid)
createdAt*string (date-time)

Vetting submission date (UTC). This is the date when the vetting request is generated

updatedAtnullable string (date-time)

Timestamp (UTC) when the brand vetting was last updated.

status*BrandVettingStatus (enum)

Identifies the vetting request status.

Example: "PENDING"
PENDINGREJECTEDFAILEDAPPROVEDEXPIRED
vettingProviderId*string

External vetting provider ID for the Brand vetting.

tokenstring
score*string

Brand vetting score (0-100). Higher is better.

class*BrandVettingClass (enum)

Identifies the vetting classification.

Example: "STANDARD"
STANDARD
reasonsarray of string

A list of reasons for FAILED vetting.

Request
const response = await fetch('/workspaces/{workspaceId}/tcr-brands/{brandId}/vettings', {
    method: 'POST',
    headers: {
      "Authorization": "Bearer jwt",
      "Content-Type": "application/json"
    },
    body: JSON.stringify({
      "class": "STANDARD"
    }),
});
const data = await response.json();
Response
{
  "id": "123e4567-e89b-12d3-a456-426614174000",
  "brandId": "123e4567-e89b-12d3-a456-426614174000",
  "createdAt": "2024-10-22T10:10:58.936Z",
  "updatedAt": "2024-10-22T10:10:58.936Z",
  "status": "PENDING",
  "vettingProviderId": "text",
  "token": "text",
  "score": "text",
  "class": "STANDARD",
  "reasons": [
    "text"
  ]
}

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.

Create campaign. A campaign can only be created for an approved brand.

POST/workspaces/{workspaceId}/tcr-brands/{brandId}/campaigns
Authorization
Path parameters
workspaceId*string
brandId*string
Body
name*string

Campaign name

usecase*string

A use case that best matches the purpose of the campaign.

subUsecasesarray of string

If use case is MIXED or LOW_VOLUME mixed an array of 2-5 use cases.

description*string

A detailed description of what the campaign is for.

embeddedLinkboolean

Whether messages will contain links. Provide at least one sample containing a link.

embeddedPhoneboolean

Whether messages will contain phone number. Provide at least one sample containing a phone number.

numberPoolboolean

Whether a campaign will be associated with more than 50 numbers e.g. customer service use case.

ageGatedboolean

Whether a campaign contains age-gated content based on carrier/ctia guidelines.

directLendingboolean

Whether a campaign includes content related to direct lending or loan arrangements.

subscriberOptinboolean

Confirm customer opt in is collected and processed.

subscriberOptoutboolean

Confirm customer opt out is collected and processed.

subscriberHelpboolean

Confirm an info message is returned if a customer sends "HELP".

samples*array of string

Between 1-5 sample messages. If directLending, embeddedPhone, embeddedLink is true provide relevant examples.

attachmentUrlsarray of string

Up to 5 attachments.

messageFlow*string

Provide details of how the customer will opt into this campaign. If you have a live web opt-in provide the URL and ensure the page has details on the T&Cs/data collection for opting in, and how to opt out.

helpMessage*string

Help message of the campaign. A help message shall state the name of the service, contact (email or call centre), OPT IN and OPT OUT keywords.

helpKeywordsstring

A comma separated list of keywords. Support of the word HELP is the minimum requirement for requesting help/info.

optoutKeywordsstring

A comma separated list of keywords. Support of the word STOP is the minimum requirement for OPT OUT.

optinKeywordsstring

A comma separated list of keywords. Support of the word START is the minimum requirement for OPT OUT.

optinMessagestring

Provide an example of the message that will be sent after a customer has opted in.

optoutMessagestring

Provide an example of the message that will be sent after a customer has opted out.

termsAndConditions*enum

Indicates the campaign follows CTIA messaging principles and best practices.

true
Response

Campaign successfully created

Body
idstring (uuid)

UUID of the campaign.

namestring

Campaign name

subscriptionCampaignSubscription

Describes status of Campaign Subscription

statusenum

Campaign status

DRAFTFAILEDPENDINGREJECTEDAPPROVEDDECLINEDSUSPENDEDDELETEDEXPIRED
usecasestring

A use case that best matches the purpose of the campaign.

subUsecasesnullable array of string

If use case is MIXED or LOW_VOLUME mixed an array of 2-5 use cases.

descriptionstring

A detailed description of what the campaign is for.

embeddedLinkboolean

Whether messages will contain links. Provide at least one sample containing a link.

embeddedPhoneboolean

Whether messages will contain phone number. Provide at least one sample containing a phone number.

numberPoolboolean

Whether a campaign will be associated with more than 50 numbers e.g. customer service use case.

ageGatedboolean

Whether a campaign contains age-gated content based on carrier/ctia guidelines.

directLendingboolean

Whether a campaign includes content related to direct lending or loan arrangements.

subscriberOptinboolean

Confirm customer opt in is collected and processed.

subscriberOptoutboolean

Confirm customer opt out is collected and processed.

subscriberHelpboolean

Confirm an info message is returned if a customer sends "HELP".

samplesarray of string

Between 1-5 sample messages. If directLending, embeddedPhone, embeddedLink is true provide relevant examples.

messageFlowstring

Provide details of how the customer will opt into this campaign. If you have a live web opt-in provide the URL and ensure the page has details on the T&Cs/data collection for opting in, and how to opt out.

helpMessagestring

Help message of the campaign. A help message shall state the name of the service, contact (email or call centre), OPT IN and OPT OUT keywords.

helpKeywordsstring

A comma separated list of keywords. Support of the word HELP is the minimum requirement for requesting help/info.

optoutKeywordsstring

A comma separated list of keywords. Support of the word STOP is the minimum requirement for OPT OUT.

optinKeywordsstring

A comma separated list of keywords. Support of the word START is the minimum requirement for OPT OUT.

optinMessagestring

Provide an example of the message that will be sent after a customer has opted in.

optoutMessagestring

Provide an example of the message that will be sent after a customer has opted out.

termsAndConditionsboolean

Indicates the campaign follows CTIA messaging principles and best practices.

brandIdstring (uuid)

UUID of the brand associated with this campaign. The specified brand MUST be APPROVED.

rejectionobject

Rejection details

attachmentsarray of Attachment (object)

Attachments associated with this campaign.

createdAtstring (date-time)

Timestamp (UTC) when the campaign was created.

updatedAtstring (date-time)

Timestamp (UTC) when the campaign was last updated.

Request
const response = await fetch('/workspaces/{workspaceId}/tcr-brands/{brandId}/campaigns', {
    method: 'POST',
    headers: {
      "Authorization": "Bearer jwt",
      "Content-Type": "application/json"
    },
    body: JSON.stringify({
      "name": "text",
      "usecase": "text",
      "description": "text",
      "samples": [
        "text"
      ],
      "messageFlow": "text",
      "helpMessage": "text",
      "termsAndConditions": true
    }),
});
const data = await response.json();
Response
{
  "id": "123e4567-e89b-12d3-a456-426614174000",
  "name": "text",
  "subscription": {
    "status": "active",
    "subscribedAt": "2024-10-22T10:10:58.936Z",
    "updatedAt": "2024-10-22T10:10:58.936Z",
    "cancelledAt": "2024-10-22T10:10:58.936Z"
  },
  "status": "DRAFT",
  "usecase": "text",
  "subUsecases": [
    "text"
  ],
  "description": "text",
  "embeddedLink": false,
  "embeddedPhone": false,
  "numberPool": false,
  "ageGated": false,
  "directLending": false,
  "subscriberOptin": false,
  "subscriberOptout": false,
  "subscriberHelp": false,
  "samples": [
    "text"
  ],
  "messageFlow": "text",
  "helpMessage": "text",
  "helpKeywords": "text",
  "optoutKeywords": "text",
  "optinKeywords": "text",
  "optinMessage": "text",
  "optoutMessage": "text",
  "termsAndConditions": false,
  "brandId": "123e4567-e89b-12d3-a456-426614174000",
  "rejection": {
    "description": "text",
    "code": "text"
  },
  "attachments": [
    {
      "id": "123e4567-e89b-12d3-a456-426614174000",
      "status": "PENDING",
      "createdAt": "2024-10-22T10:10:58.936Z",
      "updatedAt": "2024-10-22T10:10:58.936Z",
      "filename": "attachment.txt",
      "contentType": "text/plain"
    }
  ],
  "createdAt": "2024-10-22T10:10:58.936Z",
  "updatedAt": "2024-10-22T10:10:58.936Z"
}

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": "TEST",
  "usecase": "LOW_VOLUME",
  "subUsecases": [
    "MARKETING",
    "DELIVERY_NOTIFICATION",
    "2FA"
  ],
  "description": "Internal use case for TEST ONLY",
  "embeddedLink": false,
  "embeddedPhone": false,
  "numberPool": false,
  "ageGated": false,
  "directLending": false,
  "subscriberOptin": true,
  "subscriberOptout": true,
  "subscriberHelp": true,
  "samples": [
    "This is a TEST MESSAGE"
  ],
  "messageFlow": "this is an internal use case. They will only send to their own device and will not send to any external users. External users will only see SMS via screen-sharing during live or recorded demos.",
  "helpMessage": "send HELP to be connected to support",
  "helpKeywords": "HELP",
  "optoutKeywords": "STOP",
  "optinKeywords": "START",
  "optinMessage": "send Start to enable notifications and messages.",
  "optoutMessage": "send STOP to unsubscribe",
  "termsAndConditions": true
}'

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 .

Create a new connector from a template.

POST/workspaces/{workspaceId}/connectors
Authorization
Path parameters
workspaceId*string (uuid)
Body
name*connector name
connectorTemplateReftemplate to base this connector on by ref
argumentsarguments to provide to each action invocation on this connector
securityArgumentsSecurityArgumentsMap

Provide the arguments required by the security scheme(s) on the connector template.

channelConversationalStatusEnabledControls the default value for channel's conversational flag.
invitationTokenInvitation token to allow installation of connectors that are not GA.
Response

OK

Body
id*string (uuid)

The ID of this connector.

workspaceIdstring (uuid)

The ID of the workspace this connector belongs to.

routingKeynullable string
name*string

The Name of this connector.

regionstring

The Region in which this connector was installed in.

descriptionstring

The Description of this connector.

argumentsnullable object

Pre-configured arguments for this connector.

channelChannelConfig (object)
numbernullable NumberConfig (object)
connectorTemplateSlugstring

The slug for the template this connector is based on.

connectorTemplateRefstring

The ref for the template this connector is based on.

dataFetchingThe connector's data fetching synchronisation configuration and state.
dataCapturenullable object
createdAt*string (date-time)

When the connector was created.

updatedAtstring (date-time)

When the connector was last updated.

Request
const response = await fetch('/workspaces/{workspaceId}/connectors', {
    method: 'POST',
    headers: {
      "Authorization": "Bearer jwt",
      "Content-Type": "application/json"
    },
    body: JSON.stringify({
      "name": "text"
    }),
});
const data = await response.json();
Response
{
  "id": "123e4567-e89b-12d3-a456-426614174000",
  "workspaceId": "123e4567-e89b-12d3-a456-426614174000",
  "routingKey": "text",
  "name": "text",
  "region": "text",
  "description": "text",
  "arguments": {
    "someArgument": "someValue"
  },
  "channel": {
    "channelId": "123e4567-e89b-12d3-a456-426614174000",
    "platform": "text"
  },
  "number": {
    "profileId": "123e4567-e89b-12d3-a456-426614174000",
    "numberId": "123e4567-e89b-12d3-a456-426614174000",
    "phoneNumber": "text",
    "capabilities": "mms-inbound,mms-outbound,sms-inbound,sms-outbound",
    "numberType": "mobile",
    "endpointType": "alpha-number",
    "country": "NL",
    "profileAttachments": [
      {
        "capability": "text",
        "profileId": "text",
        "variables": {
          "connectorId": "text"
        }
      }
    ]
  },
  "connectorTemplateSlug": "text",
  "connectorTemplateRef": "text",
  "dataFetching": {
    "schedule": "text",
    "streams": [
      {
        "eventName": "text",
        "streamName": "text",
        "eventStreamName": "text",
        "filter": "text",
        "initialState": "text",
        "endCondition": "text",
        "incremental": false,
        "duplicatesFilterCapacity": 0,
        "cursorField": "text"
      }
    ]
  },
  "dataCapture": {
    "captureEndpoint": "text"
  },
  "createdAt": "2024-10-22T10:10:58.936Z",
  "updatedAt": "2024-10-22T10:10:58.936Z"
}

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

Show the details of a specific connector.

GET/workspaces/{workspaceId}/connectors/{connectorId}
Authorization
Path parameters
workspaceId*string (uuid)
connectorId*string (uuid)
Response

OK

Body
id*string (uuid)

The ID of this connector.

workspaceIdstring (uuid)

The ID of the workspace this connector belongs to.

routingKeynullable string
name*string

The Name of this connector.

regionstring

The Region in which this connector was installed in.

descriptionstring

The Description of this connector.

argumentsnullable object

Pre-configured arguments for this connector.

channelChannelConfig (object)
numbernullable NumberConfig (object)
connectorTemplateSlugstring

The slug for the template this connector is based on.

connectorTemplateRefstring

The ref for the template this connector is based on.

dataFetchingThe connector's data fetching synchronisation configuration and state.
dataCapturenullable object
createdAt*string (date-time)

When the connector was created.

updatedAtstring (date-time)

When the connector was last updated.

Request
const response = await fetch('/workspaces/{workspaceId}/connectors/{connectorId}', {
    method: 'GET',
    headers: {
      "Authorization": "Bearer jwt"
    },
});
const data = await response.json();
Response
{
  "id": "123e4567-e89b-12d3-a456-426614174000",
  "workspaceId": "123e4567-e89b-12d3-a456-426614174000",
  "routingKey": "text",
  "name": "text",
  "region": "text",
  "description": "text",
  "arguments": {
    "someArgument": "someValue"
  },
  "channel": {
    "channelId": "123e4567-e89b-12d3-a456-426614174000",
    "platform": "text"
  },
  "number": {
    "profileId": "123e4567-e89b-12d3-a456-426614174000",
    "numberId": "123e4567-e89b-12d3-a456-426614174000",
    "phoneNumber": "text",
    "capabilities": "mms-inbound,mms-outbound,sms-inbound,sms-outbound",
    "numberType": "mobile",
    "endpointType": "alpha-number",
    "country": "NL",
    "profileAttachments": [
      {
        "capability": "text",
        "profileId": "text",
        "variables": {
          "connectorId": "text"
        }
      }
    ]
  },
  "connectorTemplateSlug": "text",
  "connectorTemplateRef": "text",
  "dataFetching": {
    "schedule": "text",
    "streams": [
      {
        "eventName": "text",
        "streamName": "text",
        "eventStreamName": "text",
        "filter": "text",
        "initialState": "text",
        "endCondition": "text",
        "incremental": false,
        "duplicatesFilterCapacity": 0,
        "cursorField": "text"
      }
    ]
  },
  "dataCapture": {
    "captureEndpoint": "text"
  },
  "createdAt": "2024-10-22T10:10:58.936Z",
  "updatedAt": "2024-10-22T10:10:58.936Z"
}

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

Create a Workspace Webhook Subscription

Create a workspace webhook subscription

POST/organizations/{organizationId}/workspaces/{workspaceId}/webhook-subscriptions
Authorization
Path parameters
workspaceId*Workspace ID

The ID for the workspace.

organizationId*Organization ID

The ID for the organization.

Body
service*string
event*string
eventFiltersnullable array of WebhookEventFilter (object)
templatestring
url*URL
Pattern: ^https://([a-zA-Z0-9-]+\.)+[a-zA-Z]{2,}(/[^\s]*)?$
signingKeystring
Response

Created

Body
id*string (uuid)
organizationId*string (uuid)
workspaceId*string (uuid)
service*string
event*string
eventFiltersarray of WebhookEventFilter (object)
templatestring
url*string
Pattern: ^https://[^\s/$.?#].[^\s]*$
signingKeystring
status*WebhookSubscriptionStatus (enum)
activeinactive
createdAtstring (date-time)
updatedAtstring (date-time)
Request
const response = await fetch('/organizations/{organizationId}/workspaces/{workspaceId}/webhook-subscriptions', {
    method: 'POST',
    headers: {
      "Authorization": "Bearer jwt",
      "Content-Type": "application/json"
    },
    body: JSON.stringify({
      "service": "text",
      "event": "text",
      "url": "text"
    }),
});
const data = await response.json();
Response
{
  "id": "123e4567-e89b-12d3-a456-426614174000",
  "organizationId": "123e4567-e89b-12d3-a456-426614174000",
  "workspaceId": "123e4567-e89b-12d3-a456-426614174000",
  "service": "text",
  "event": "text",
  "eventFilters": [
    {
      "key": "text",
      "value": "text"
    }
  ],
  "template": "text",
  "url": "text",
  "signingKey": "text",
  "status": "active",
  "createdAt": "2024-10-22T10:10:58.936Z",
  "updatedAt": "2024-10-22T10:10:58.936Z"
}

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)

Linking will trigger the connector status field "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