Registering an agent
Create an RCS brand and agent with POST /v1/rcs/agents, answer our review, test on your own phones and send the launch details to the carriers.
When you finish this page you have an RCS agent on its way to the carriers and know how to follow it to live. You need a profile for the agent's inbox, usage-based billing and a card on file.
Step 1: Upload the logo and banner
Carriers require a 224x224 logo under 50 KB and a 1440x448 banner under 200 KB. Upload any PNG, JPEG or WebP to POST /v1/rcs/assets with kind set to logo or banner; it is cropped and compressed to the exact size and you get back a URL for the agent.
curl -X POST "https://zernio.com/api/v1/rcs/assets" \
-H "Authorization: Bearer $ZERNIO_API_KEY" \
-F "kind=logo" \
-F "file=@logo.png"Response (200):
{ "url": "https://media.zernio.com/rcs-assets/1790000000000_ab12cd34_logo.jpg" }Step 2: Request the agent
Call POST /v1/rcs/agents with the profile, the agent and either a new brand or the brandId of a brand you registered before. Send one or the other, never both. One profile holds one open agent.
curl -X POST "https://zernio.com/api/v1/rcs/agents" \
-H "Authorization: Bearer $ZERNIO_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: 4f7c1c9e-agent-northside" \
-d '{
"profileId": "66c3d2ae7b4f6c8d0e1f2a3b",
"brand": {
"displayName": "Northside Shoes",
"legalName": "Northside Shoes LLC",
"legalEntityType": "LIMITED_LIABILITY_COMPANY",
"organizationType": "PRIVATE_PROFIT",
"websiteUrl": "https://northsideshoes.example.com",
"taxId": "12-3456789",
"address": { "line1": "212 Market St", "city": "Chicago", "state": "IL", "postalCode": "60606", "country": "US" },
"contact": { "firstName": "Dana", "lastName": "Reyes", "title": "Head of CX", "email": "dana@northsideshoes.example.com", "phone": "+13125550123" }
},
"displayName": "Northside Shoes",
"useCase": "MULTI_USE",
"profile": {
"description": "Order updates, delivery alerts and member offers.",
"logoUrl": "https://media.zernio.com/rcs-assets/1790000000000_ab12cd34_logo.jpg",
"heroUrl": "https://media.zernio.com/rcs-assets/1790000000001_ef56ab78_banner.jpg",
"brandColor": "#1A73E8",
"privacyPolicyUrl": "https://northsideshoes.example.com/privacy",
"termsUrl": "https://northsideshoes.example.com/terms",
"phone": { "number": "+13125550123", "label": "Call us" },
"email": { "address": "help@northsideshoes.example.com", "label": "Email us" }
},
"smsFallbackFrom": "+13125550199"
}'Response (201):
{
"agent": {
"id": "6aba8af3e7aba406647e82a1",
"profileId": "66c3d2ae7b4f6c8d0e1f2a3b",
"accountId": null,
"country": "US",
"status": "requested",
"displayName": "Northside Shoes",
"useCase": "MULTI_USE",
"smsFallbackFrom": "+13125550199",
"testDevices": [],
"carrierApprovals": []
}
}What the fields need:
- Brand: the exact legal name, tax ID and address the government has on record. In the US
taxIdis the EIN andstateis required; elsewhere use the national tax or company registration number.contact.emailmust be a named person on the company domain: Gmail,info@andsupport@are rejected by the carriers. Public companies addstockSymbolasEXCHANGE:SYMBOL. - Agent:
displayNameup to 40 characters,descriptionup to 100,useCaseone ofTRANSACTIONAL,PROMOTIONAL,MULTI_USEorOTP.brandColoris a six-digit hex with at least 4.5:1 contrast on white. At least a phone or an email contact button is required; a website alone is not enough. - Fallback:
smsFallbackFromis optional and must be one of your SMS-enabled numbers.
Step 3: Our review
Nothing reaches the carriers, and nothing is charged, until we review the request. If something needs fixing the agent moves to changes_requested with a note in reviewNote. Fix it with PATCH /v1/rcs/agents/{agentId}, sending only the fields that change; that puts it back in our queue as requested.
curl -X PATCH "https://zernio.com/api/v1/rcs/agents/6aba8af3e7aba406647e82a1" \
-H "Authorization: Bearer $ZERNIO_API_KEY" \
-H "Content-Type: application/json" \
-d '{"profile": {"description": "Order updates and delivery alerts.", "logoUrl": "https://media.zernio.com/rcs-assets/1790000000000_ab12cd34_logo.jpg", "heroUrl": "https://media.zernio.com/rcs-assets/1790000000001_ef56ab78_banner.jpg", "brandColor": "#1A73E8", "privacyPolicyUrl": "https://northsideshoes.example.com/privacy", "termsUrl": "https://northsideshoes.example.com/terms", "phone": {"number": "+13125550123", "label": "Call us"}}}'Once the details are filed with the carriers they are locked, and only smsFallbackFrom can still change.
Follow progress with the rcs.agent.status_updated webhook instead of polling:
{
"id": "evt_9f2c1b7a",
"event": "rcs.agent.status_updated",
"agent": { "id": "6aba8af3e7aba406647e82a1", "displayName": "Northside Shoes", "profileId": "66c3d2ae7b4f6c8d0e1f2a3b", "accountId": null },
"status": "changes_requested",
"reason": "The EIN does not match the legal name on file. Send the name exactly as it appears on your IRS letter.",
"timestamp": "2027-01-04T10:12:00.000Z"
}Step 4: Test on your phones (US)
After our review a US agent goes through company vetting and agent review with the carriers. When it reaches testing it can message phones you invite, and nobody else. Invite a phone with POST /v1/rcs/agents/{agentId}/test-devices; the invite has to be accepted in the phone's messaging app before messages arrive. T-Mobile and AT&T numbers cannot be test phones.
curl -X POST "https://zernio.com/api/v1/rcs/agents/6aba8af3e7aba406647e82a1/test-devices" \
-H "Authorization: Bearer $ZERNIO_API_KEY" \
-H "Content-Type: application/json" \
-d '{"phoneNumber": "+13125550188"}'Response (201):
{ "testDevice": { "testDeviceId": "0d7c5f0e-2a41-4c7a-9f7e-3b8b1f6f2c10", "phoneNumber": "+13125550188", "inviteStatus": "PENDING" } }GET on the same path lists invited phones and their inviteStatus (PENDING, ACCEPTED or DECLINED); DELETE .../test-devices/{testDeviceId} removes one.
Step 5: Send the launch details
The carriers review what the agent will send and how people agree to receive it. Send it with POST /v1/rcs/agents/{agentId}/launch-request:
- United States: once the agent is in
testingand works on your phones. It moves tolaunch_reviewfor our check, thenlaunching. - Other markets: right after the request, while it is still
requested,changes_requestedorbrand_vetting. We file it with the carriers together with the agent; the status does not change.
curl -X POST "https://zernio.com/api/v1/rcs/agents/6aba8af3e7aba406647e82a1/launch-request" \
-H "Authorization: Bearer $ZERNIO_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"companyOverview": "Northside Shoes sells running and lifestyle shoes online and in 12 stores in Illinois.",
"agentOverview": "Order confirmations, delivery updates and support replies to customers who opted in at checkout.",
"interactions": [{ "type": "TRANSACTIONAL_UPDATES" }, { "type": "CUSTOMER_SUPPORT" }],
"messageExamples": [
"Your order #4821 has shipped and arrives Thursday.",
"Your return for order #4790 was received. Your refund is on its way.",
"Hi Sam, thanks for your message. What size do you need?"
],
"consent": {
"optInMethods": [{ "type": "WEBSITE" }],
"callToAction": "Tick \"Send me order updates by message\" at checkout. Reply STOP to opt out.",
"callToActionUrl": "https://northsideshoes.example.com/checkout",
"callToActionMediaUrl": "https://northsideshoes.example.com/img/optin.png",
"doubleOptIn": false,
"optInMessage": "You are subscribed to Northside Shoes messages. Reply STOP to opt out, HELP for help.",
"helpResponse": "Northside Shoes: for help call +1 312 555 0123. Reply STOP to opt out.",
"optOutResponse": "You are unsubscribed from Northside Shoes. Reply START to resubscribe."
},
"testVideoUrl": "https://videos.example.com/northside-rcs-test.mp4"
}'messageExamples needs at least three. A WEBSITE opt-in needs callToActionUrl and a screenshot in callToActionMediaUrl; a MOBILE_APP opt-in needs the screenshot. testVideoUrl is a public or unlisted video of a test phone sending START, STOP and HELP to the agent plus one real conversation.
When the carriers approve, the agent becomes live, can message any RCS-capable phone, and its accountId is the inbox account it sends from.
If it fails
A 409 means the profile already has an open agent, the brand you reused was rejected, or the agent is past the point where that change is allowed. A 422 with USAGE_BILLING_REQUIRED means the workspace is not on usage-based billing, and a 402 means no card is on file. If the carriers reject the agent it becomes rejected with the reason in declineReason. DELETE /v1/rcs/agents/{agentId} deactivates an agent: it stops sending and monthly billing stops from the next month. Every error uses the envelope in error handling.