Add an SMS market — a country and sender type
Gives the customer a sender in one country — the first market it sends in, and the fifth.
What to have in place first
Call GET /v3/compliance/requirements?country=US&type=TEN_DLC first. It returns this request's body ready to fill in, plus the brand and campaign calls to make before it, in order. You never have to track forty countries' rules yourself.
A market that registers with a compliance regime needs an identity, and this call takes one. US TEN_DLC registers with The Campaign Registry and files that registration against a business identity. Send it in compliance.brand and it is recorded here, before the registration that attaches to it — so a customer with no identity reaches a first 10DLC market in one call.
{ "inherit": true } runs on your organization's instead. A market with neither — none stored, none sent — is 400, because accepting it would write a channel that could never register and leave it provisioning for ever with nothing saying why.
Everything the regime wants arrives in this request's compliance, as two declared objects: brand — the identity the registration is filed against — and campaign, with the use case, the consent narrative, the volume, the sample messages and the keywords. There is nothing to set up first. Nothing is submitted here either: the rows are what a submission is later assembled from, and filing is externally rejectable so it happens on its own path.
A market that registers with nobody — an alphanumeric sender in most countries — needs neither, and may need documents instead.
Sending it
Takes the same fields channels.sms takes on POST /v3/sender-profiles, because it is the same work, and both run one provisioning path. compliance is top-level and answers for the market in this request, carrying brand and campaign where the market registers.
Accepts multipart as well as JSON, with each file named after the compliance key it satisfies — a market that pre-registers its sender needs its documents at the same moment it needs the sender.
A market the customer already holds is 409: adding what is already there is a mistake worth reporting rather than a silent no-op. A market is a (country, sender_type) pair, so a second sender type in a country you already send in is fine — US TOLL_FREE alongside US TEN_DLC is the ordinary case. Two of the same type is not.
One exception: while a market's sender type is still unassigned, adding any type to that country is 409, because the market you have may be about to become the one you asked for.
Returns the market, in the shape GET and PATCH on /v3/channels/sms/{country}/{type} use — so what this answers can be read back and written back without reshaping, and compliance.requirements names what it still owes. Not every channel you have: adding a market cannot change an RCS agent or a WhatsApp account, and GET /v3/channels is the whole picture. 201 when the market is ready; 202 while a sender or a registration is still outstanding.
Send x-profile-id with an organization key to add a market to one of your profiles.
TypeScript Definitions
Use the request body type in TypeScript.
Response Body
application/json
application/json
application/json
application/json
application/json
application/json
curl -X POST "https://example.com/v3/channels/sms" \ -H "Idempotency-Key: req_abc123_retry1" \ -H "Content-Type: application/json" \ -d '{ "number_type": "TEN_DLC" }'{
"success": true,
"data": {
"country": "string",
"number_type": "string",
"sender_value": "string",
"status": "PROVISIONING",
"compliance": {
"brand": {
"property1": null,
"property2": null
},
"campaign": {
"property1": null,
"property2": null
},
"documents": [
{
"key": "string",
"file_name": "string",
"document_id": "b792e8ae-2cb4-4209-85b9-32be4c2fcdd6"
}
]
}
},
"error": {
"code": "string",
"message": "string",
"details": {
"property1": [
"string"
],
"property2": [
"string"
]
},
"doc_url": "string"
},
"meta": {
"request_id": "string",
"timestamp": "2019-08-24T14:15:22Z",
"version": "string"
}
}{
"success": true,
"data": {
"country": "string",
"number_type": "string",
"sender_value": "string",
"status": "PROVISIONING",
"compliance": {
"brand": {
"property1": null,
"property2": null
},
"campaign": {
"property1": null,
"property2": null
},
"documents": [
{
"key": "string",
"file_name": "string",
"document_id": "b792e8ae-2cb4-4209-85b9-32be4c2fcdd6"
}
]
}
},
"error": {
"code": "string",
"message": "string",
"details": {
"property1": [
"string"
],
"property2": [
"string"
]
},
"doc_url": "string"
},
"meta": {
"request_id": "string",
"timestamp": "2019-08-24T14:15:22Z",
"version": "string"
}
}{
"success": true,
"error": {
"code": "string",
"message": "string",
"details": {
"property1": [
"string"
],
"property2": [
"string"
]
},
"doc_url": "string"
},
"meta": {
"request_id": "string",
"timestamp": "2019-08-24T14:15:22Z",
"version": "string"
}
}{
"success": true,
"error": {
"code": "string",
"message": "string",
"details": {
"property1": [
"string"
],
"property2": [
"string"
]
},
"doc_url": "string"
},
"meta": {
"request_id": "string",
"timestamp": "2019-08-24T14:15:22Z",
"version": "string"
}
}{
"success": true,
"error": {
"code": "string",
"message": "string",
"details": {
"property1": [
"string"
],
"property2": [
"string"
]
},
"doc_url": "string"
},
"meta": {
"request_id": "string",
"timestamp": "2019-08-24T14:15:22Z",
"version": "string"
}
}{
"success": true,
"error": {
"code": "string",
"message": "string",
"details": {
"property1": [
"string"
],
"property2": [
"string"
]
},
"doc_url": "string"
},
"meta": {
"request_id": "string",
"timestamp": "2019-08-24T14:15:22Z",
"version": "string"
}
}Get one SMS market (country and sender type) GET
Reads one market you send in — its sender, where that sender stands, and everything its compliance holds. ## What `compliance` carries A market that registers with a compliance regime reports `brand` — the identity the registration is filed against — and `campaign`, the programme filed against it. Each carries `inherit`, saying whether it is yours or your organization's. A market that registers with nobody has neither, so **both keys are absent** rather than null: absent says this market does not ask, where null would say it asks and you supplied nothing. It reports `documents` instead. `requirements` lists what is still owed, keyed as you write it — `brand.legal_name`, `campaign.message_flow`. ## Writing it back **`PATCH` this same path**, with the `compliance` object from this response: ```json { "compliance": { "brand": { "tax_id": "12-3456789" } } } ``` Nothing else to learn — what comes back can be sent back, an omitted key is left alone, and a `requirements` key is the path into the body that clears it. There is no sub-resource for either half: both are singletons of the market, so both are written here. `GET /v3/compliance/requirements` says what a market demands of anybody; this says what you gave it. Send `x-profile-id` with an organization key to read one of your profiles' markets.
Amend one SMS market's compliance PATCH
Writes what this market declares for compliance, and answers with the market as stored — the same shape `GET` on this path returns, so **what comes back can be sent back**. ## Partial, at every level **An omitted key is left alone. An explicit `null` clears it.** Those are different requests, so `{}` changes nothing and is refused rather than silently accepted, and correcting one field does not blank the others. ```json { "compliance": { "brand": { "contact_phone": "+12125550123" } } } ``` That leaves the campaign untouched, along with every other field of the identity. ## What a US `TEN_DLC` market holds Two halves, both singular: `brand`, the identity the registration is filed against, and `campaign`, the programme filed against it. Each carries `inherit`. | Body | Effect | | --- | --- | | `"brand": { … }` | supplies or corrects the identity, and takes one of your own | | `"brand": { "inherit": true }` | runs on your organization's, giving up your own | | `"brand": null` | the same thing, said the short way | | `"campaign": { … }` | supplies or corrects the programme, and takes one of your own | | `"campaign": { "inherit": true }` | runs on your organization's | | key omitted | left exactly as it is | **Nothing here creates a second anything.** One identity and one campaign per market, so a write is an upsert and a replayed request lands on the row it already wrote. Sending the campaign twice does not file two registrations. ## Every other market Markets that register with no regime have neither half — their compliance is documents, which cannot be JSON values and are sent as multipart on `POST /v3/channels/sms`. Only US `TEN_DLC` registers, so this path is `404` everywhere else. ## What it will refuse **A filed identity is `409`.** Once the registration has gone to The Campaign Registry they hold a copy, and a local change would diverge from it silently. The campaign is not frozen — omit `brand` and the same body is accepted. **More than one campaign is `409`.** The schema permits several and an account built on the admin side may hold them; this surface writes one, and editing whichever sorted first would leave the others unmentioned and unedited. Nothing is submitted to a regime here. These are the rows a submission is later assembled from, which is what lets them be corrected without waiting on something externally rejectable. Send `x-profile-id` with an organization key to write one of your profiles' markets.