10DLC Campaigns
On this page
Create, submit, update and monitor 10DLC campaigns through TNID, including submitting a campaign automatically once its brand is verified.
A campaign registers a messaging use case (marketing, customer care, 2FA and so on) under an ACTIVE brand. Numbers are attached to campaigns; carriers use the campaign to decide throughput and filtering.
All 10DLC operations are on the /company GraphQL server with a company token. Every operation is documented with request, variables and response in the API Reference.
Campaign lifecycle
| Status | Meaning |
|---|---|
DRAFT |
Saved in TNID, not sent to TCR. |
PENDING |
Submitted to TCR (or waiting for the brand to become ACTIVE). |
ACTIVE |
Approved. Numbers can be assigned. |
ERROR |
Submission failed. Fix and resubmit with updateAndSubmitTenDlcCampaign. |
EXPIRED, SUSPENDED |
No longer usable for traffic. |
These are campaign statuses. Brand statuses are a different set (PENDING_REVIEW belongs to brands).
Three ways to submit
| Mutation | When to use it |
|---|---|
registerAndSubmitTenDlcCampaign(input) |
The brand is already ACTIVE. Creates the campaign and submits it to TCR immediately. |
registerTenDlcCampaignWhenReady(input) |
The brand is still under review. TNID stores the campaign as PENDING and submits it automatically when the brand becomes ACTIVE. |
saveTenDlcCampaignAsDraft(input) then updateTenDlcCampaignAsDraft(id, input) |
You want to build the campaign up over time before submitting. |
mutation ($input: TenDlcRegisterCampaignInput!) {
registerAndSubmitTenDlcCampaign(input: $input) {
campaignId
brandId
usecase
status
description
messageFlow
autoRenewal
}
}
{
"input": {
"tenDlcApiKeyId": "<id returned by addTenDlcApiKey>",
"internalBrandId": "<TNID id of the brand, from tenDlcBrands.records.id>",
"usecase": "MARKETING",
"description": "Promotions and product launches for opted-in customers",
"messageFlow": "Customers opt in by texting JOIN to our number or ticking the box at checkout. They receive up to 4 messages a month.",
"sample1": "Acme: Summer sale starts today. Show this text in store for 10% off. Reply STOP to opt out, HELP for help.",
"subscriberOptin": true,
"subscriberOptout": true,
"subscriberHelp": true,
"termsAndConditions": true,
"nnid": "<your NNID, if you have one>",
"resellerId": "<CSP reseller id, if applicable>"
}
}
campaignId (for example CZDFL35) is the TCR identifier. updateAndSubmitTenDlcCampaign(id, input) changes a submitted campaign and re-syncs it with TCR, which is also the path after an ERROR. deleteTenDlcCampaign(id) removes it.
Monitor campaigns and their numbers
query ($brandId: String, $status: TenDlcCampaignStatus, $usecase: String, $page: Int, $pageSize: Int) {
tenDlcCampaigns(brandId: $brandId, status: $status, usecase: $usecase, page: $page, pageSize: $pageSize) {
page
totalRecords
records {
id
campaignId
brandId
usecase
status
workflowStatus
autoRenewal
ownershipType
}
}
}
tenDlcCampaign(id) returns the full record (message flow, opt-in/opt-out/help settings, expiration and billing dates). tenDlcCampaignWithTelephoneNumbers(id) adds the numbers attached to the campaign with their carrier workflow statuses (osrWorkflowStatus, tmobileWorkflowStatus), which is the quickest way to see whether a number is cleared to send.
Sending traffic
TNID registers the campaign. Sending messages on the registered numbers happens through your messaging provider; on TSG Global, assign the campaign to a number with the campaign_id field of the SMS enablement endpoint.
What to read next
- 10DLC Brands: the brand must be
ACTIVEfirst. - Webhooks: get notified instead of polling.
- API Reference: all 23 10DLC operations.