Amend one SMS market's compliance

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.

{ "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.

BodyEffect
"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": nullthe 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 omittedleft 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.

PATCH
/v3/channels/sms/{country}/{type}

Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

Response Body

application/json

application/json

application/json

application/json

application/json

curl -X PATCH "https://example.com/v3/channels/sms/string/string" \  -H "Idempotency-Key: req_abc123_retry1" \  -H "Content-Type: application/json" \  -d '{    "property1": null,    "property2": null  }'
{
  "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"
  }
}
Empty
Empty
{
  "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"
  }
}

Add an SMS market — a country and sender type POST

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.

Add a WhatsApp account POST

Connects a WhatsApp Business Account shared with us through a Multi-Partner Solution to the calling sender profile. Send `x-profile-id` for the profile the account belongs to. **Two fields, because everything else is derived.** `waba_id` says which of your organization's shared accounts this is — you hold one per client, and nothing else can say which. `phone_number_id` says which number on it to send from — an account may hold several, and choosing for you would mean deciding which of your customer's numbers their traffic leaves from. The solution the account arrived through, the client business portfolio that owns it, the access token and its expiry are all resolved from your organization. They are not accepted here: the first two are Meta's answer about provenance, and the token is minted per client business and rotates roughly every sixty days, so a value you sent would be stale before it was useful. `phone_number_id` is optional. Omit it to connect the account now and settle the number later — the channel reads as `provisioning` and the profile keeps sending from your organization's account until a number is named. The same resolution runs behind `channels.whatsapp` on `POST /v3/sender-profiles`, so connecting at create and connecting afterwards fill the same fields. Returns **the account**, not every channel you have — adding one cannot change a market or an RCS agent, and `GET /v3/channels` is the whole picture. Giving an account up is not self-service: ask support, because deregistering a number lands in your own Meta business.