10DLC Compliance API
Register brands, create messaging campaigns, and manage 10DLC compliance for US SMS.
10DLC registration is required for sending SMS at volume on US phone numbers. Without it, carriers will filter your messages and delivery rates will drop significantly. Complete brand registration and campaign approval before scaling SMS operations.
Brands
Brands represent your business identity in the 10DLC ecosystem. You must register and vet a brand before creating messaging campaigns.
List brands
GET /compliance/brands
Returns all brands registered under your account.
curl "https://api.trunx.io/compliance/brands" \
-H "Authorization: Bearer tk_live_..."const res = await fetch("https://api.trunx.io/compliance/brands", {
headers: { "Authorization": "Bearer tk_live_..." },
});
const data = await res.json();Register brand
POST /compliance/brands
Submit your business information for 10DLC registration with The Campaign Registry (TCR).
Request body
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Legal business name |
ein | string | Yes | Employer Identification Number (e.g., 12-3456789) |
vertical | string | Yes | Business vertical (use /compliance/enums/vertical to list valid values) |
entityType | string | Yes | Entity type (e.g., PRIVATE_PROFIT, PUBLIC_PROFIT, NON_PROFIT) |
country | string | No | Country code (default: US) |
website | string | No | Business website URL |
email | string | No | Contact email |
phone | string | No | Contact phone in E.164 format |
curl -X POST "https://api.trunx.io/compliance/brands" \
-H "Authorization: Bearer tk_live_..." \
-H "Content-Type: application/json" \
-d '{
"name": "Acme Corp",
"ein": "12-3456789",
"vertical": "TECHNOLOGY",
"entityType": "PRIVATE_PROFIT",
"website": "https://acme.com",
"email": "compliance@acme.com",
"phone": "+14155551234"
}'const res = await fetch("https://api.trunx.io/compliance/brands", {
method: "POST",
headers: {
"Authorization": "Bearer tk_live_...",
"Content-Type": "application/json",
},
body: JSON.stringify({
name: "Acme Corp",
ein: "12-3456789",
vertical: "TECHNOLOGY",
entityType: "PRIVATE_PROFIT",
website: "https://acme.com",
email: "compliance@acme.com",
phone: "+14155551234",
}),
});
const brand = await res.json();Response
{
"id": "brand_abc123",
"name": "Acme Corp",
"ein": "12-3456789",
"vertical": "TECHNOLOGY",
"entityType": "PRIVATE_PROFIT",
"country": "US",
"website": "https://acme.com",
"email": "compliance@acme.com",
"phone": "+14155551234",
"status": "PENDING",
"createdAt": "2026-03-11T18:00:00.000Z"
}Get brand details
GET /compliance/brands/{id}
Returns full details for a specific brand, including current registration status.
Update brand
PUT /compliance/brands/{id}
Update brand information. Accepts the same fields as brand registration.
Updating a brand may require re-vetting depending on which fields changed. Check the brand status after updating.
Delete brand
DELETE /compliance/brands/{id}
Delete a brand registration. This will fail if the brand has active campaigns associated with it.
Brand qualification status
GET /compliance/brands/{id}/qualify
Check whether a brand qualifies for 10DLC messaging and which campaign use cases are available.
Resubmit for vetting
POST /compliance/brands/{id}/revet
Resubmit a brand for vetting after corrections have been made. Use this if a previous vetting attempt was rejected.
Brand feedback
GET /compliance/brands/{id}/feedback
Retrieve feedback from The Campaign Registry (TCR) about the brand registration, including rejection reasons or required corrections.
Apply for external vetting
POST /compliance/brands/{id}/vetting/apply
Submit the brand for third-party external vetting. External vetting can unlock higher messaging throughput tiers.
External vetting typically takes 1-3 business days and may incur an additional fee. Brands with external vetting receive higher message throughput limits from carriers.
List vetting records
GET /compliance/brands/{id}/vettings
Returns all vetting records for a brand, including status and outcomes.
[
{
"vettingId": "vet_001",
"vettingClass": "STANDARD",
"status": "APPROVED",
"completedAt": "2026-03-10T12:00:00.000Z"
}
]Campaigns (10DLC)
Campaigns define the messaging use case and are required before sending SMS through assigned DIDs. Each campaign is linked to a registered brand.
List campaigns
GET /compliance/campaigns
Returns all 10DLC campaigns for your account.
Create campaign
POST /compliance/campaigns
Register a new 10DLC messaging campaign under a vetted brand.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
brandId | string | Yes | ID of the registered brand |
usecase | string | Yes | Campaign use case (e.g., MARKETING, CUSTOMER_CARE, DELIVERY_NOTIFICATIONS) |
description | string | Yes | Plain-language description of the campaign's purpose |
sampleMessages | string[] | Yes | 2-5 sample messages that represent typical content |
subscriberOptIn | boolean | Yes | Confirms opt-in consent is collected |
subscriberHelp | boolean | Yes | Confirms HELP keyword response is implemented |
numberPool | boolean | No | Whether multiple numbers will send on behalf of this campaign |
curl -X POST "https://api.trunx.io/compliance/campaigns" \
-H "Authorization: Bearer tk_live_..." \
-H "Content-Type: application/json" \
-d '{
"brandId": "brand_abc123",
"usecase": "MARKETING",
"description": "Promotional offers for opted-in customers",
"sampleMessages": [
"Hi {name}, 20% off this weekend! Reply STOP to opt out.",
"Flash sale today only -- shop now at acme.com. Reply STOP to unsubscribe."
],
"subscriberOptIn": true,
"subscriberHelp": true,
"numberPool": true
}'const res = await fetch("https://api.trunx.io/compliance/campaigns", {
method: "POST",
headers: {
"Authorization": "Bearer tk_live_...",
"Content-Type": "application/json",
},
body: JSON.stringify({
brandId: "brand_abc123",
usecase: "MARKETING",
description: "Promotional offers for opted-in customers",
sampleMessages: [
"Hi {name}, 20% off this weekend! Reply STOP to opt out.",
"Flash sale today only -- shop now at acme.com. Reply STOP to unsubscribe.",
],
subscriberOptIn: true,
subscriberHelp: true,
numberPool: true,
}),
});
const campaign = await res.json();Response
{
"id": "camp_xyz789",
"brandId": "brand_abc123",
"usecase": "MARKETING",
"description": "Promotional offers for opted-in customers",
"status": "PENDING",
"createdAt": "2026-03-11T18:30:00.000Z"
}Get campaign details
GET /compliance/campaigns/{id}
Returns full campaign details including carrier approval status.
Update campaign
PUT /compliance/campaigns/{id}
Update campaign details. Changes may trigger re-review by carriers.
Delete campaign
DELETE /compliance/campaigns/{id}
Delete a 10DLC campaign. This will unlink all assigned DIDs.
Nudge campaign review
POST /compliance/campaigns/{id}/nudge
Send a nudge to expedite the carrier review process for a pending campaign.
Expedite vetting
POST /compliance/campaigns/{id}/expedite
Request expedited vetting for a campaign. This may incur additional fees.
List assigned numbers
GET /compliance/campaigns/{id}/numbers
Returns all DIDs currently assigned to the campaign.
Assign DIDs to campaign
POST /compliance/campaigns/{id}/numbers/assign
Assign phone numbers to a 10DLC campaign. Numbers must be provisioned in your account before assignment.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
numbers | string[] | Yes | Array of E.164 phone numbers to assign |
curl -X POST "https://api.trunx.io/compliance/campaigns/camp_xyz789/numbers/assign" \
-H "Authorization: Bearer tk_live_..." \
-H "Content-Type: application/json" \
-d '{"numbers": ["+14155559876", "+14155559877"]}'const res = await fetch(
"https://api.trunx.io/compliance/campaigns/camp_xyz789/numbers/assign",
{
method: "POST",
headers: {
"Authorization": "Bearer tk_live_...",
"Content-Type": "application/json",
},
body: JSON.stringify({
numbers: ["+14155559876", "+14155559877"],
}),
}
);
const result = await res.json();DIDs can only be assigned to one 10DLC campaign at a time. Assigning a DID that is already linked to another campaign will return a 409 Conflict error.
Remove DIDs from campaign
POST /compliance/campaigns/{id}/numbers/remove
Remove phone numbers from a 10DLC campaign.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
numbers | string[] | Yes | Array of E.164 phone numbers to remove |
Carrier approval details
GET /compliance/campaigns/{id}/carriers
Returns per-carrier approval status for a campaign. Different carriers may approve at different times.
{
"campaignId": "camp_xyz789",
"carriers": [
{ "carrier": "AT&T", "status": "APPROVED", "approvedAt": "2026-03-12T10:00:00.000Z" },
{ "carrier": "T-Mobile", "status": "APPROVED", "approvedAt": "2026-03-12T14:00:00.000Z" },
{ "carrier": "Verizon", "status": "PENDING", "approvedAt": null }
]
}Utility
DID-to-campaign mapping
GET /compliance/did-mapping
Returns a mapping of all DIDs to their assigned 10DLC campaigns. Useful for auditing which numbers are registered and which are unassigned.
[
{ "number": "+14155559876", "campaignId": "camp_xyz789", "campaignStatus": "APPROVED" },
{ "number": "+14155559877", "campaignId": "camp_xyz789", "campaignStatus": "APPROVED" },
{ "number": "+19495551234", "campaignId": null, "campaignStatus": null }
]Get enum values
GET /compliance/enums/{name}
Returns valid enum values for compliance fields. Use this to populate dropdowns or validate input before submission.
| Enum name | Description |
|---|---|
vertical | Business verticals (e.g., TECHNOLOGY, HEALTHCARE, FINANCE) |
entityType | Entity types (e.g., PRIVATE_PROFIT, PUBLIC_PROFIT, NON_PROFIT, GOVERNMENT) |
usecase | Campaign use cases (e.g., MARKETING, CUSTOMER_CARE, DELIVERY_NOTIFICATIONS, ACCOUNT_NOTIFICATION) |
curl "https://api.trunx.io/compliance/enums/vertical" \
-H "Authorization: Bearer tk_live_..."{
"name": "vertical",
"values": [
"AGRICULTURE",
"COMMUNICATION",
"EDUCATION",
"ENTERTAINMENT",
"FINANCE",
"GAMBLING",
"GOVERNMENT",
"HEALTHCARE",
"HOSPITALITY",
"INSURANCE",
"LEGAL",
"MANUFACTURING",
"NGO",
"POLITICAL",
"REAL_ESTATE",
"RELIGION",
"RETAIL",
"TECHNOLOGY",
"TRANSPORTATION"
]
}