# RCS sender An RCS sender represents your brand identity used to deliver RCS messages via Sinch Conversation API. This guide shows how developers prepare and launch a sender with the Provisioning API, including what you need up front and how to track its lifecycle. For messaging usage and APIs, see Conversation API docs: [Conversation API overview](https://developers.sinch.com/docs/conversation). What you'll find here: - Prerequisites: account, project credentials, and project id - Creating a sender: request shape and sample code - Questionnaire: data required by suppliers/operators - Launching: making your sender available beyond test devices - Status model: how sender, country, and operator statuses relate ## Prerequisites Before creating an RCS sender, ensure you have: - A Sinch account: Register and sign in via Sinch Build: [dashboard.sinch.com](https://dashboard.sinch.com/) - Project credentials: Create an Access Key and Access Secret for the specific project you intend to use. These credentials authenticate calls to Provisioning API and Sinch Build. - Project ID: The UUID of the project that will own the sender. You can create a sender using either route: - Provisioning API: Programmatic REST interface suitable for backend automation and CI/CD. - Sinch Build: Web console workflow for interactive creation and management. Quick links: - Sinch Build dashboard: [dashboard.sinch.com](https://dashboard.sinch.com/) - Create project credentials: [Access Keys](https://dashboard.sinch.com/settings/access-keys) - RCS Senders (create API): [Create Sender](https://developers.sinch.com/docs/provisioning-api/api-reference/provisioning-api/rcs-senders/rcssenderscontroller_createsender_v1) ## The questionnaire In order to successfully launch an RCS sender, the questionnaire must first be completed. The questionnaire collects various data and answers different questions asked by Suppliers and Operators, in order for them to approve the RCS Sender. The questionnaire consists of at least two parts. The `general` property includes all questions that are used for all markets, and the `verification` property contains information used to verify that RCS Sender is allowed to be launched. In addition to these, there may be country specific questions. The country specific questions are additional information that is required by local regulations or local Suppliers or Operators. All required questions are returned in the Sender object, but it can also be retrieved beforehand with [get questionnaire request](/docs/provisioning-api/api-reference/provisioning-api/rcs-questionnaire/questionnairecontroller_getquestions_v1): ```javascript import fetch from "node-fetch"; async function getQuestionnaire(useCase, countryCode) { const response = await fetch( `https://provisioning.api.sinch.com/v1/projects/${PROJECT_ID}/rcs/questionnaire/${useCase}?countries=${countryCode}`, { method: "GET", headers: { "Content-Type": "application/json", Authorization: "Basic " + Buffer.from(ACCESS_KEY + ":" + ACCESS_SECRET).toString("base64"), }, } ); const data = await response.json(); return data; } ``` Quick links: - API reference – RCS Questionnaire (get): [Get Questionnaire](https://developers.sinch.com/docs/provisioning-api/api-reference/provisioning-api/rcs-questionnaire/questionnairecontroller_getquestions_v1) Especially the country specific questions may be subject to change, depending on the requirements by local regulations, Suppliers or Operators. Any change will be announced in CHANGELOG, with grace period if possible. ## Creating a sender The following **Node.js** code sample demonstrates how to make a request to add a [new RCS sender](/docs/provisioning-api/api-reference/provisioning-api/rcs-senders/rcssenderscontroller_createsender_v1) for a specific project: ```javascript import fetch from "node-fetch"; async function createSender() { const response = await fetch( `https://provisioning.api.sinch.com/v1/projects/${PROJECT_ID}/rcs/senders`, { method: "POST", headers: { "Content-Type": "application/json", Authorization: "Basic " + Buffer.from(ACCESS_KEY + ":" + ACCESS_SECRET).toString("base64"), }, body: JSON.stringify({ region: "EU", billingCategory: "BASIC_MESSAGE", useCase: "PROMOTIONAL", details: { brand: { emails: [ { label: "Contact email", address: "contact@test.com", }, ], phones: [ { label: "Contact phone", number: "+33 777-777-777", }, { label: "Helpdesk", number: "+48 888-888-888", }, ], websites: [ { label: "Website", url: "https://test.com", }, ], name: "Sender name", description: "Sender description", color: "#000000", bannerUrl: "https://example-banner-url.com", logoUrl: "https://example-logo-url.com", privacyPolicyUrl: "https://example-privacy-policy-url.com", termsOfServiceUrl: "https://example-terms-of-service-url.com", }, callbackUrl: "https://example-callback-url.com", testNumbers: ["+33 000111222"], countries: ["PL", "GB", "FR"], questionnaire: { general: { answers: { optInDescription: "By making a purchase in-store or online", triggerDescription: "User actions (e.g. after making a purchase)", interactionsDescription: "Promotional offers", optOutDescription: "Thank you for unsubscribing", videoUris: ["https://example-video-url.com"], }, }, verification: { answers: { name: "Verification contact", email: "verification@test.com", title: "Head of verification", website: "https://verification.test.com", }, }, gb: { answers: { brandIndustry: "Automotive", messagesVolume: "10K - 100K messages", messagesFrequency: "Once per month", campaignLength: "6 months", }, }, fr: { answers: { fullCompanyAddress: "123 Rue des Fleurs, 75001 Paris, France", usersAmount: "10k - 100K users", startDate: "Within 3 months", }, }, }, }, }), } ); const data = await response.json(); return data; } ``` Quick links: - API reference – RCS Senders (create): [Create Sender](https://developers.sinch.com/docs/provisioning-api/api-reference/provisioning-api/rcs-senders/rcssenderscontroller_createsender_v1) ## Launching a sender Until a sender is launched, it can only interact with specified test devices. Launching the sender makes it accessible to all devices. The code below shows how to make a [launch request](/docs/provisioning-api/api-reference/provisioning-api/rcs-senders/senderscontroller_launchsender_v1) for a sender: ```javascript import fetch from "node-fetch"; async function launchSender() { const response = await fetch( `https://provisioning.api.sinch.com/v1/projects/${PROJECT_ID}/rcs/senders/${SENDER_ID}/launch`, { method: "POST", headers: { "Content-Type": "application/json", Authorization: "Basic " + Buffer.from(ACCESS_KEY + ":" + ACCESS_SECRET).toString("base64"), }, } ); const data = await response.json(); return data; } ``` Quick links: - API reference – RCS Senders (launch): [Launch Sender](https://developers.sinch.com/docs/provisioning-api/api-reference/provisioning-api/rcs-senders/senderscontroller_launchsender_v1) - Webhooks overview (status tracking): [Webhooks](https://developers.sinch.com/docs/provisioning-api/api-reference/provisioning-api/webhooks) The sender endpoints return a full sender object that includes sender state. The state refers to the various operational statuses that a sender can have throughout its lifecycle. Normally it transitions from `IN_TEST` upon sender creation to `LAUNCHING` when a launch request is made, and finally to `LAUNCHED` when the launch has been successful on any of the available mobile operators. Notifications are triggered on change of sender state and operator status, which can be tracked via Webhooks. ## Understanding RCS Sender States and Statuses RCS senders have a hierarchical status system consisting of three levels: sender state, country status, and operator status. The operator statuses are aggregated to determine the country status, and the country statuses are aggregated to determine the overall sender state. ### RCS Sender State The sender state represents the overall status of the RCS sender across all countries and operators. When a sender is created, it immediately transitions to `IN_TEST` state. It remains in this state until you initiate a launch request. When you launch a sender, it transitions to either `LAUNCHING` or `PREPARING_LAUNCH`. The `PREPARING_LAUNCH` state indicates that Sinch needs to perform certain actions before the sender can progress to `LAUNCHING`. Once the first operator has been successfully launched, the sender state changes to `LAUNCHED`. If all operators are unlaunched (removed at customer request), the sender state becomes `UNLAUNCHED`, meaning it can no longer send messages. ```mermaid stateDiagram-v2 [*] --> IN_TEST: Sender created IN_TEST --> PREPARING_LAUNCH: Launch requested (requires preparation) IN_TEST --> LAUNCHING: Launch requested (direct launch) PREPARING_LAUNCH --> LAUNCHING: Preparation completed, continue launching LAUNCHING --> LAUNCHED: First operator launched LAUNCHED --> UNLAUNCHED: All operators unlaunched UNLAUNCHED --> [*] ``` **Available sender states:** - `DRAFT` - Initial state before creation (currently not in use) - `IN_PROGRESS` - Sender creation is in progress (currently not in use, as creation is synchronously completed) - `IN_TEST` - Sender can only interact with test devices - `PREPARING_LAUNCH` - Sinch is performing pre-launch actions - `LAUNCHING` - Launch is in progress - `LAUNCHED` - At least one operator is live - `UNLAUNCHED` - Sender has been removed - `IN_PROGRESS` - Transitional state during updates - `UNKNOWN` - State cannot be determined ### Country Status Each country where the sender is configured has its own status, which is derived from the statuses of all operators within that country. When you launch a sender, the operators in each country transition from `NOT_LAUNCHED` to `PENDING`. Once an operator approves the launch, it becomes `LAUNCHED`, and the country status also becomes `LAUNCHED`. If an operator rejects the launch request, it transitions to `REJECTED` (usually with a remark explaining why). If all operators in a country are rejected, the country status becomes `REJECTED`. After launch, an operator may suspend the sender due to policy violations or incorrect usage, transitioning to `SUSPENDED` (usually with a remark explaining the reason). If all operators in a country are suspended, the country status becomes `SUSPENDED`. When you request removal of operators, they transition to `PENDING_UNLAUNCHED` and eventually to `UNLAUNCHED`. If all operators in a country are unlaunched, the country status becomes `UNLAUNCHED`. ```mermaid stateDiagram-v2 [*] --> NOT_LAUNCHED NOT_LAUNCHED --> PENDING: Launch requested PENDING --> LAUNCHED: Operator approved PENDING --> REJECTED: Operator rejected LAUNCHED --> SUSPENDED: Suspended by operator due to policy violation LAUNCHED --> PENDING_UNLAUNCHED: Unlaunch requested by customer SUSPENDED --> PENDING_UNLAUNCHED: Unlaunch requested by customer REJECTED --> PENDING_UNLAUNCHED: Unlaunch requested by customer PENDING_UNLAUNCHED --> UNLAUNCHED: Unlaunch completed UNLAUNCHED --> [*] ``` **Available country statuses:** - `NOT_LAUNCHED` - Operators not yet submitted for launch - `PENDING` - Launch request submitted, awaiting approval - `LAUNCHED` - At least one operator is live - `REJECTED` - All operators rejected the launch request - `SUSPENDED` - All operators have suspended the sender - `PENDING_UNLAUNCHED` - Unlaunch request in progress - `UNLAUNCHED` - All operators have been removed - `INVALID_IN_GOOGLE_MY_BUSINESS` - Google My Business verification issue - `UNRECOGNIZED` - Status cannot be determined ### Operator Status Each mobile operator within a country has its own status. These are the most granular statuses and directly reflect the approval state with each individual operator. When launching a sender, operators transition from `NOT_LAUNCHED` to `PENDING`. After the operator's approval process: - If approved, the status becomes `LAUNCHED` - If rejected, the status becomes `REJECTED` (with a remark explaining the rejection reason) Once launched, an operator may `SUSPEND` the sender due to policy violations or incorrect usage (with a remark explaining the reason). When requesting removal, the operator status transitions to `PENDING_UNLAUNCHED` and eventually to `UNLAUNCHED`. ```mermaid stateDiagram-v2 [*] --> NOT_LAUNCHED NOT_LAUNCHED --> PENDING: Launch requested PENDING --> LAUNCHED: Operator approved PENDING --> REJECTED: Operator rejected LAUNCHED --> SUSPENDED: Suspended by operator due to policy violation LAUNCHED --> PENDING_UNLAUNCHED: Unlaunch requested by customer SUSPENDED --> PENDING_UNLAUNCHED: Unlaunch requested by customer REJECTED --> PENDING_UNLAUNCHED: Unlaunch requested by customer PENDING_UNLAUNCHED --> UNLAUNCHED: Unlaunch completed UNLAUNCHED --> [*] ``` **Available operator statuses:** - `NOT_LAUNCHED` - Not yet submitted for launch - `PENDING` - Submitted to operator, awaiting approval - `LAUNCHED` - Approved and live - `REJECTED` - Launch request rejected (check remark for details) - `SUSPENDED` - Suspended due to policy violation (check remark for details) - `PENDING_UNLAUNCHED` - Unlaunch request in progress - `UNLAUNCHED` - Removed from operator - `INVALID_IN_GOOGLE_MY_BUSINESS` - Google My Business verification issue - `UNRECOGNIZED` - Status cannot be determined ### Status Hierarchy Example Here's an example of how the statuses work together: 1. **Initial state**: Sender is `IN_TEST`, all countries are `NOT_LAUNCHED`, all operators are `NOT_LAUNCHED` 2. **After launch request**: Sender becomes `LAUNCHING`, countries become `PENDING`, operators become `PENDING` 3. **First operator approval**: Sender becomes `LAUNCHED`, that country becomes `LAUNCHED`, that operator becomes `LAUNCHED` 4. **Operator rejection in another country**: That specific operator becomes `REJECTED`, if all operators in that country are rejected, the country becomes `REJECTED`, but the sender remains `LAUNCHED` (since at least one operator is live) 5. **Policy violation**: An operator becomes `SUSPENDED`, if all operators in a country are suspended, the country becomes `SUSPENDED`