This guide walks through how to programmatically submit a brand and agent for carrier approval. The same process happens when you use the launch wizard in RCS Studio — the API gives you direct control over each step.
Overview
A brand represents your legal business entity. An agent is the verified RCS sender tied to that brand. Before an agent can send messages to real users, both must be reviewed and approved by carriers.
When you submit your brand and agent details, Vibes reviews them first. Once approved internally, Vibes routes the details to the appropriate parties on your behalf — brand and agent basics go to Aegis Mobile for identity vetting, and campaign and testing details go to carriers and Google for content and compliance review.
To provision a brand and agent via the API, you follow the same two-operation flow for each resource:
- PATCH the brand or agent to set the required details
- POST to
.../submitto lock and submit those details for review
You can run PATCH requests at any time and build up the data incrementally. Submitting is what triggers the review process.
Order of operations
The diagram below shows the full flow — who acts at each step, and what conditions must be met before you can proceed.
flowchart TD
classDef you fill:#dbeafe,stroke:#3b82f6,color:#1d4ed8
classDef vibes fill:#fef3c7,stroke:#d97706,color:#92400e
classDef ext fill:#d1fae5,stroke:#059669,color:#065f46
classDef gate fill:#f3f4f6,stroke:#6b7280,color:#111827
PB["Step 1 — PATCH /brands/:brandId<br/>Set brand details"]:::you
SB["Step 2 — POST /brands/:brandId/submit"]:::you
VB["Vibes reviews brand"]:::vibes
PA["Step 3 — PATCH /agents/:agentId<br/>Set agent basics, campaign & testing"]:::you
S1["Step 4 — submit type: 'basics'"]:::you
S2["submit type: 'campaign'"]:::you
S3["submit type: 'testing'"]:::you
V1["Vibes reviews<br/>brand + agent basics"]:::vibes
AE["Aegis Mobile<br/>Brand + agent basics vetting"]:::ext
V2["Vibes reviews<br/>campaign + testing"]:::vibes
CR["Carriers + Google<br/>Content & compliance review"]:::ext
LIVE[["🎉 Agent Live"]]:::gate
PB --> SB --> VB
VB -- "✓ Brand approved by Vibes" --> S1
VB -. "changes requested" .-> PB
PA --> S1
S1 --> S2 --> S3
S1 --> V1 --> AE
S2 --> V2
S3 --> V2
V2 --> CR
AE & CR --> LIVE
| Color | Who |
|---|---|
| 🔵 Blue | API calls you make |
| 🟡 Yellow | Vibes internal review |
| 🟢 Green | External — Aegis Mobile, carriers, Google |
Key conditions:
- You can PATCH brand and agent details at any time and submit each section as soon as it's ready — you don't need to wait for Aegis Mobile, carrier, or Google approvals before submitting the next section. The one hard prerequisite is that the brand must have been submitted (i.e.
POST /brands/:brandId/submitmust have been called) before any agentsubmitcall is accepted — the brand does not need to be fully approved first. - The lifecycle always progresses in the same fixed order regardless of when you submit: Vibes reviews internally first, then routes brand and agent basics to Aegis Mobile for identity vetting, then routes campaign and testing to carriers and Google for content review. Vibes manages all handoffs — you submit, and the status updates will always follow that sequence.
- Aegis vetting is triggered after Vibes reviews the agent
basicssubmission — at that point Vibes submits both the brand and agent basics to Aegis together - Brand is submitted and approved once — additional agents under the same brand skip steps 1–2
If changes are requested or a submission is rejected: PATCH the brand or agent with the corrected details, then call the relevant submit endpoint again. Vibes will notify you by email when action is needed.
There are currently no webhooks for status changes. PollGET /brands/:brandIdandGET /agents/:agentIdto check current status. See Agent status lifecycle for what each status means.
Step 1 — Patch brand details
PATCH https://api.rcsstudio.ai/brands/{brandId}
Authorization: Bearer <access_token>
Content-Type: application/jsonBrand details are submitted to Vibes and forwarded to Aegis Mobile for vetting. Every field must match your official business records.
Request example, field reference, and errors
{
"legalName": "Acme Corp LLC",
"legalEntityType": "LIMITED_LIABILITY_COMPANY",
"organizationType": "PRIVATE_PROFIT",
"identifiers": [
{ "type": "EIN", "value": "123456789" }
],
"addresses": [
{
"line1": "123 Main St",
"city": "Chicago",
"state": "IL",
"postalCode": "60601",
"country": "US"
}
],
"websites": [
{ "url": "https://www.acmecorp.com" }
],
"contacts": [
{
"type": "BRAND",
"firstName": "Jane",
"lastName": "Smith",
"title": "VP of Marketing",
"phone": "+12125551234",
"email": "[email protected]"
}
]
}Top-level fields
| Field | Description | Required | Validation |
|---|---|---|---|
legalName | Legal business name | Yes | Must match your IRS CP 575 letter exactly |
legalEntityType | Legal entity type | Yes | One of: LIMITED_LIABILITY_COMPANY, SOLE_PROPRIETORSHIP, PARTNERSHIP, CORPORATION, S_CORPORATION |
organizationType | Organization type | Yes | One of: PRIVATE_PROFIT, PUBLIC_PROFIT, NON_PROFIT, GOVERNMENT, UNKNOWN |
identifiers[]
| Field | Description | Required | Validation |
|---|---|---|---|
type | Identifier type | Yes | One of: EIN, STOCK_SYMBOL |
value | Identifier value | Yes | EIN: 9–10 characters. Stock symbol: <exchange>:<symbol> format (e.g. NASDAQ:ACME). Publicly traded companies should include both. |
addresses[]
| Field | Description | Required | Validation |
|---|---|---|---|
line1 | Street address | Yes | — |
line2 | Suite, floor, etc. | No | — |
city | — | Yes | — |
state | — | Yes | — |
postalCode | — | Yes | — |
country | — | Yes | — |
websites[]
| Field | Description | Required | Validation |
|---|---|---|---|
url | Official business website URL | Yes | — |
contacts[]
The BRAND contact type is the point of contact for carrier vetting. This person receives a verification email from Aegis Mobile — use a company-domain email address. Public email providers (Gmail, Yahoo, etc.) are not accepted.
| Field | Description | Required | Validation |
|---|---|---|---|
type | Contact type | Yes | One of: PRIMARY, OFFICER, AGENT, RESPONSIBLE_PARTY, BILLING, BRAND, UNKNOWN |
firstName | — | Yes | — |
lastName | — | Yes | — |
title | Job title | No | — |
phone | Contact phone number | No | Max 16 characters. Include country code (e.g. +12125551234). |
email | Email address | Yes | Must be a valid email address. BRAND contact must use a company-domain address. |
Common errors
| Error | Cause |
|---|---|
"Brand cannot be updated in its current status" | Brand has already been submitted and is locked for changes. Only brands in a pre-submission or failed state can be patched. |
Step 2 — Submit brand
POST https://api.rcsstudio.ai/brands/{brandId}/submit
Authorization: Bearer <access_token>No request body. This submits the brand for Vibes' internal review and unlocks agent submit calls — you do not need to wait for brand approval before proceeding to Step 3. Vibes may request changes before approving, and you will be notified by email.
Aegis Mobile vetting does not begin at this step — it is initiated later, when you submit the agent basics. At that point, Vibes submits both the brand and agent basics to Aegis together.
A brand only needs to be submitted once. Once approved, you can provision additional agents under the same brand without resubmitting.
Required fields and errors
Required at brand submit time
| Field | Requirement |
|---|---|
legalName | Must be present |
legalEntityType | Must be present |
organizationType | Must be present |
identifiers | At least one EIN identifier required. If organizationType is PUBLIC_PROFIT, at least one STOCK_SYMBOL is also required. |
addresses | At least one address required |
contacts | At least one contact required |
websites | At least one website URL required |
Common errors
| Error | Cause |
|---|---|
"Brand is not ready to launch yet" | Brand is either freshly created (no details patched yet) or a submission is already in progress. |
"Missing required fields: ..." | One or more required fields are missing. See required fields above. |
Step 3 — Patch agent details
PATCH https://api.rcsstudio.ai/agents/{agentId}
Authorization: Bearer <access_token>
Content-Type: application/jsonAgent details are split into three objects: basics, campaign, and testing. You can patch any combination of them in a single request and update them incrementally before submitting.
Request body
{
"basics": { ... },
"campaign": { ... },
"testing": { ... }
}basics — agent appearance
basics — agent appearanceControls how the agent appears to users in their messaging app.
Request example, field reference, and errors
{
"basics": {
"name": "Acme Rewards",
"description": "Rewards program updates and offers",
"logoUri": "https://cdn.acmecorp.com/logo.png",
"heroUri": "https://cdn.acmecorp.com/banner.png",
"color": "#2A7AE4",
"phoneNumber": { "number": "+18005551234", "label": "Customer Support" },
"website": { "url": "https://www.acmecorp.com", "label": "Visit us" },
"email": { "address": "[email protected]", "label": "Email us" },
"privacyUri": "https://www.acmecorp.com/privacy",
"termsConditionsUri": "https://www.acmecorp.com/terms"
}
}| Field | Description | Required | Validation |
|---|---|---|---|
name | Display name shown to users | Yes | Max 40 characters |
description | Short, purpose-based description shown on the agent card. Not a marketing tagline — required by U.S. carriers. | Yes | Max 100 characters |
logoUri | Agent logo URL. PNG or JPEG, 224×224 px, max 256 KB. Displayed as a circular image. | Yes | Must start with http:// or https:// |
heroUri | Agent banner URL. PNG or JPEG, 1440×448 px, max 512 KB. | Yes | Must start with http:// or https:// |
color | Brand color displayed on the agent card | Yes | Valid 3- or 6-digit hex (#RGB or #RRGGBB). Must meet 2:1 contrast ratio. |
phoneNumber.number | Contact phone number shown on the agent card | No | Max 16 characters. Include country code (e.g. +12125551234). |
phoneNumber.label | Label shown alongside the phone number | No | Max 25 characters |
website.url | Contact website URL shown on the agent card | No | Must start with http:// or https://. Set to empty string to clear. |
website.label | Label shown alongside the website link | No | Max 25 characters |
email.address | Contact email address shown on the agent card | No | Must be a valid email address. Set to empty string to clear. |
email.label | Label shown alongside the email address | No | Max 25 characters |
privacyUri | Privacy policy URL | Yes | Must start with http:// or https:// |
termsConditionsUri | Terms of service URL | Yes | Must start with http:// or https:// |
At least one contact method (phoneNumber,website, or
Common errors
| Error | Cause |
|---|---|
"Agent basics cannot be updated in its current status" | The agent has progressed past a state where agent basics can be edited (e.g. it is under carrier review). |
campaign — messaging purpose and consent
campaign — messaging purpose and consentCarriers use this to confirm what you'll actually send matches what you've declared. Be specific — vague descriptions are a common rejection reason.
Request example, field reference, and errors
{
"campaign": {
"companyOverview": "A national retail brand selling apparel across the US.",
"agentOverview": "Sends order confirmations, shipping updates, and loyalty rewards to opted-in customers.",
"interactions": [
{ "type": "TransactionalUpdates" },
{ "type": "LoyaltyOrReward" }
],
"messageExamples": [
{ "messageText": "Your order #12345 has shipped. Track it here: https://track.acme.com/12345" },
{ "messageText": "You've earned 200 rewards points! Your balance is now 1,450 points." },
{ "messageText": "Your return for order #11234 has been processed. Refund arrives in 3–5 business days." }
],
"consentSettings": {
"optInMethods": [{ "type": "Website" }],
"ctaText": "Sign up for order updates",
"ctaLink": "https://www.acmecorp.com/signup",
"ctaUri": "https://cdn.acmecorp.com/cta-screenshot.png",
"optInMessage": { "messageText": "You're subscribed to Acme order updates. Reply STOP to opt out." },
"helpResponse": { "messageText": "Acme Rewards: For help, call 1-800-555-1234 or visit acmecorp.com/help. Reply STOP to opt out." },
"optOutResponse": "You've been unsubscribed from Acme Rewards messages. No further messages will be sent."
}
}
}Top-level fields
| Field | Description | Required | Validation |
|---|---|---|---|
companyOverview | What your company does — not what the agent does. Example: "A national retail brand selling apparel", not "A messaging agent". | Yes | Max 2000 characters |
agentOverview | How this specific agent will be used. Must align with the configured use case. | Yes | Max 2000 characters |
interactions[] | Interaction types that apply to this agent | Yes | At least one required. Types: TransactionalUpdates, CustomerSupport, LoyaltyOrReward, MarketingOrPromotional, AccountAlerts, TwoWayConversation, Other (requires an other explanation string). |
messageExamples[] | Representative messages users will receive. Use real examples — not placeholders. | Yes | At least 3 required. Max 2000 characters each. |
consentSettings fields
| Field | Description | Required | Validation |
|---|---|---|---|
optInMethods[] | How users opt in to receive messages | Yes | At least one required. Types: SMS, Website, MobileApp, QRCode, SalePoint, Other. |
ctaText | Call-to-action text shown to users at opt-in | No | — |
ctaLink | URL of the opt-in page. Privacy policy and terms must be accessible from this URL. | Conditional | Required if any opt-in method is Website |
ctaUri | URL of a screenshot of the opt-in CTA. Must be publicly accessible. | Conditional | Required if any opt-in method is Website or MobileApp |
optInMessage.messageText | Message sent when a user completes opt-in | Yes | Must include required compliance disclosures |
helpResponse.messageText | Response sent to the HELP keyword | Yes | Must include brand name and a support contact |
optOutResponse | Response sent to STOP/QUIT/CANCEL/END/UNSUBSCRIBE | Yes | Must confirm no further messages will be sent |
doubleOptIn | Whether double opt-in is enabled | No | — |
doubleOptInMessage.messageText | Confirmation message sent as the second opt-in step | Conditional | Required if doubleOptIn is true |
Review the RCS Studio Compliance Index and Carrier's Prohibited Content Policies before filling in these fields. Prohibited or restricted content will result in rejection.
Common errors
| Error | Cause |
|---|---|
"Campaign cannot be updated after submission" | Campaign has already been submitted. Contact Vibes support if you need to make changes. |
testing — carrier testing materials
testing — carrier testing materialsCarriers test the agent directly before approving it. The link.uri is required; additionalInfo is where you include a preview video URL.
T-Mobile requires handset testing of the START, HELP, and STOP keywords. If your test keyword differs from START, include that inadditionalInfo. Google and AT&T accept a preview video — the video must be at a public URL and show the opt-in flow, opt-out, and core functionality.
Request example, field reference, and errors
{
"testing": {
"link": {
"messageId": "welcome-message",
"uri": "https://link.rcsstudio.ai/acme-start"
},
"additionalInfo": "Preview video: https://cdn.acmecorp.com/rcs-demo.mp4. Shows opt-in flow, HELP response, STOP response, and core loyalty features."
}
}| Field | Description | Required | Validation |
|---|---|---|---|
link.messageId | ID of the entry point message the testing URL opens | No | — |
link.uri | A short link pointing to the agent's entry message | Yes | — |
additionalInfo | Additional context for carriers. Include your preview video URL here. | No | Max 2000 characters |
Common errors
| Error | Cause |
|---|---|
"Carrier testing cannot be updated after submission" | Testing has already been submitted. Contact Vibes support if you need to make changes. |
Step 4 — Submit agent
The three submissions must happen in order: basics first, then campaign, then testing.
POST https://api.rcsstudio.ai/agents/{agentId}/submit
Authorization: Bearer <access_token>
Content-Type: application/jsonEach call locks that section for review. Once all three are submitted, Vibes compiles the details into an RCS Program Brief and submits it to carriers on your behalf.
Request example, field reference, and errors
{ "type": "basics" }| Field | Description | Required | Validation |
|---|---|---|---|
type | The section of the agent submission to submit | Yes | One of: basics, campaign, testing |
Common errors
| Error | Applies to | Cause |
|---|---|---|
"Agent is not ready to launch yet" | basics | Agent is not connected to the RCS network yet (still provisioning), or its Google agent ID is in a pending state. |
"Brand must be sent to verification" | basics | POST /brands/:brandId/submit has not been called yet. Submit the brand before submitting the agent. |
"Campaign data must be submitted before carrier testing" | testing | campaign must be submitted before testing. |
"Campaign has already been submitted for this agent" | campaign | Campaign has already been submitted. Use PATCH to update and resubmit only if Vibes requests changes. |
"Carrier testing has already been submitted for this agent" | testing | Testing has already been submitted. |
"Missing required fields: ..." | All | Required fields for this submission type have not been populated on the agent. PATCH the agent with the missing data (see Step 3) before submitting. |
Check status
There are no webhooks for submission status changes. Poll the brand and agent endpoints to track progress.
GET https://api.rcsstudio.ai/brands/{brandId}
Authorization: Bearer <access_token>GET https://api.rcsstudio.ai/agents/{agentId}
Authorization: Bearer <access_token>The response includes a status field on both the brand and agent. See Agent status lifecycle for what each status means and whether any action is required from you.
Key fields to watch on the agent response:
| Field | What it tells you |
|---|---|
status | Overall agent status |
campaignStatus | Whether campaign details have been submitted |
testingStatus | Whether carrier testing materials have been submitted |
Agent status codes
The API returns more granular status codes than what is shown in the RCS Studio UI. The table below maps each API value to the corresponding status on the Agent status lifecycle page.
| API status | UI status | What it means |
|---|---|---|
CREATED | Created | Agent is being provisioned and connected to Google's RCS network (~5 minutes). |
DEPLOYED | Test Mode | Agent is connected and ready for testing with test devices. |
DEPLOY_FAILED | Setup Failed | Agent failed to connect to the RCS network. Contact Vibes support. |
DEPLOY_UPDATE_FAILED | Setup Failed | An update to the agent's RCS configuration failed. Contact Vibes support. |
VERIFICATION_REVIEW_NEEDED | Under Review | Agent basics have been submitted and are queued for Vibes internal review. |
VERIFICATION_IN_PROGRESS | Under Review | Vibes review is in progress; details are being submitted to Aegis Mobile and carriers. |
VERIFICATION_FAILED | — | A submission was rejected. Check your email from Vibes for details, then PATCH and resubmit. |
VERIFIED | Verified | Agent has passed Aegis Mobile vetting. Carrier review is in progress. |
LAUNCH_IN_PROGRESS | Verified | Carrier approvals are being finalized. |
LAUNCHED | Live | Agent is approved and live for real users on all selected carriers. |
Brand status codes
| API status | UI status | What it means |
|---|---|---|
CREATED | Created | Brand is being provisioned. |
DEPLOYED | Deployed | Brand is provisioned and ready for agent submissions. |
DEPLOY_FAILED | — | Brand deployment failed. Contact Vibes support. |
VERIFICATION_REVIEW_NEEDED | Under Review | Brand details have been submitted and are queued for Vibes internal review. |
VERIFICATION_IN_PROGRESS | Under Review | Vibes review is in progress. |
VERIFICATION_FAILED | — | Brand verification was rejected. PATCH brand details and resubmit. |
VERIFIED | Verified | Brand has passed Aegis Mobile vetting. |
Typical timelines
Once all submissions are in, Vibes handles the rest — you don't interact with Aegis or carriers directly.
| Stage | Who | Typical duration |
|---|---|---|
| Brand + agent basics review | Vibes | 2–3 business days |
| Brand + agent basics vetting | Aegis Mobile | Varies |
| Campaign + testing review | Vibes | 2–3 business days |
| Carrier + Google approvals | AT&T, T-Mobile, Verizon, Google | ~2.5 weeks |
Poll GET /agents/:agentId to check status. See Agent status lifecycle for a full description of each status and what, if anything, is required from you.
See also
- Agent status lifecycle — Status reference and what each status means
- Update brand — API reference
- Submit brand — API reference
- Update agent — API reference
- Submit agent — API reference