Add an RCS agent

Asks for an RCS agent and records the order form the carriers vet it against. Always 202: an agent is approved by the carriers, not by this call, and nothing here can make that happen sooner.

What it asks for

The RCS Agent Order Form — the same one our team fills in on your behalf today, so nothing has to be collected from you twice.

Required, because US carriers refuse a submission without them:

  • brand_name — the brand this agent presents. Not taken from compliance.brand: a business may present a different brand on RCS than the one its 10DLC registration is filed against, and the carriers vet this one.
  • privacy_policy_url and terms_and_conditions_url — fetched over the public internet at review time, so they must be absolute http(s) URLs. One behind a login passes this call and fails the review.

Everything else is optional here and can follow. display_name, description, agent_use_case and brand_color are collected as the submission is assembled; hosting_region (us or eu) defaults to us and cannot be changed once approved; billing_category (CONVERSATIONAL, SINGLE_MESSAGE, BASIC_MESSAGE) defaults to CONVERSATIONAL. Contact details, official_address, the consent narrative and the start/help/stop messages are all part of the form.

Anything supplied is checked against the accepted values rather than passed through: a value the provider rejects would otherwise surface days later, to somebody who cannot fix it without asking you.

logo_url and banner_url are validated as URLs only. The form also specifies 224x224 and 50 KB for the logo and 1440x448 and 200 KB for the banner, which cannot be checked without the image bytes.

A customer has one agent. Asking again while you have one is 409.

What comes back, and what does not

Returns the agent — the form as stored, plus id and status. Not your other channels, which this call cannot have changed.

status is PROVISIONING until the agent is handed to the carriers and approved. GET /v3/channels reports rcs: null until then — a channel row is what routing reads to decide you are sendable, and writing one for an unapproved agent would claim a channel that cannot carry traffic.

Send x-profile-id with an organization key to ask for one of your profiles' agents.

POST
/v3/channels/rcs

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 POST "https://example.com/v3/channels/rcs" \  -H "Idempotency-Key: req_abc123_retry1" \  -H "Content-Type: application/json" \  -d '{}'
{
  "success": true,
  "data": {
    "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
    "status": "PROVISIONING",
    "phone_number": "string",
    "display_name": "string",
    "description": "string",
    "agent_use_case": "string",
    "brand_name": "string",
    "privacy_policy_url": "string",
    "terms_and_conditions_url": "string",
    "website_url": "string",
    "brand_color": "string",
    "brand_phone_number": "string",
    "customer_support_phone_number": "string",
    "brand_email": "string",
    "customer_support_email": "string",
    "contact_name_and_title": "string",
    "company_ein": "string",
    "entity_type": "string",
    "official_address": {
      "street": "string",
      "city": "string",
      "state": "string",
      "postal_code": "string",
      "country": "string"
    },
    "brief_company_description": "string",
    "opt_in_process_description": "string",
    "start_message": "string",
    "help_message": "string",
    "stop_message": "string",
    "sample_messages": [
      "string"
    ],
    "created_at": "2019-08-24T14:15:22Z"
  },
  "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 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.

Get compliance requirements for a market GET

**Call this first.** It returns what a channel, country and sender type demand before you can send there — and `setup[]`, the calls that satisfy those demands, in order, each with a body you can copy and send as it stands. You never have to track forty countries' rules yourself. ## Channel `channel` is `sms`, `whatsapp` or `rcs`, and **defaults to `sms`** — so a caller that omits it gets exactly what this endpoint has always returned. `sms` is the only one answered today; the other two are `501` until their requirements are declared. They are refused rather than answered with an empty requirement set, because empty would say the channel demands nothing, and both demand plenty — WhatsApp a business verification and a display name review, RCS a carrier approval. Saying "not yet" is the true answer and the same one `POST /v3/sender-profiles` gives for `channels.whatsapp`. `type` is an SMS sender type, and SMS is the only channel whose senders have one. Requirements vary enormously. US `TEN_DLC` registers a brand and a campaign with The Campaign Registry and asks for a substantial set of values. An alphanumeric sender in one country pre-registers with supporting documents; in another it needs nothing at all. This is the authoritative answer for whichever market you are asking about, and it is the same declaration used to validate the calls themselves — so it can never drift from what is actually enforced. ## `setup[]` — what to do **One step.** `POST /v3/channels/sms` adds the market and records everything it registers with — the identity in `compliance.brand`, the programme in `compliance.campaign`. There were three, in a load-bearing order, while the identity and the campaign were resources of their own; they are members of this call's body now, so there is nothing to sequence. Correct any of it afterwards with `PATCH /v3/channels/sms/{country}/{type}`, which takes the same `compliance` object one key at a time. Each step's `body` has every key that market wants already present, with the values left **blank**. Blank rather than filled with placeholders, because the body is meant to be sent: a null value counts as not supplied, so posting a step verbatim comes back naming every blank you left. `attachments[]` lists files to send as multipart on the channel call, each under the field name given — a file cannot be a JSON value, so documents are never listed in `compliance[]`. Every step is a call for whoever holds the key. To set a **sender profile** up instead, send the same requests with the `x-profile-id` header naming it; there is no separate path. ## `requirements[]` — what each value means Each entry names a key for the `compliance` array, its value type, and whether it is required. `required_when` marks values needed only in certain cases — evaluate it against your own payload, e.g. `brand.entity_type == PUBLIC_PROFIT`. `options` lists accepted values where the market constrains them, and `label` is suitable for rendering a form field. Values Sent supplies on your behalf are never listed: correlation ids, environment flags, carrier elections, and booleans derivable from what you already send. ## When nothing is required `required` is `false` and `requirements` is empty, and the single `setup` step carries no `compliance` array at all. A `sender_id_pattern` may still be present — many markets constrain the sender string without registering anything.