RCS API
The RCS API lets external systems send RCS messages, manage agents and templates, schedule campaigns and retrieve reports.
Contents
- Access and authentication
- Endpoints
- Agents
- Message content
- Templates
- Transactional messages
- Test messages
- Campaigns
- Reports
- Errors
- Best practices
Access and authentication
API base URL:
https://api.sare.pl/ext/rcs/v1Include an authorization header in every request:
Authorization: Bearer <integrationKey>:<secret>Warning
Do not include the integration key or secret in frontend application code, URL parameters or logs. Generating a new secret invalidates the previous one.
Rate limits
POST /messages: 35 requests per second- Other endpoints: 30 requests per minute
- Limits apply to the combination of IP address and credentials
- Exceeding a limit returns
429
Endpoints
| Method | Path | Purpose |
|---|---|---|
GET | /agents | List available agents |
PATCH | /agents/{agentId} | Update an agent |
POST | /templates | Create a template |
GET | /templates | List templates |
GET | /templates/{id} | Get template details |
PUT | /templates/{id} | Replace an entire template |
DELETE | /templates/{id} | Delete a template |
POST | /messages | Send a transactional message |
POST | /messages/test | Send a test message |
GET | /messages/{messageId} | Get message status |
POST | /campaigns | Schedule a campaign |
GET | /campaigns/{id} | Get campaign status |
GET | /reports/campaigns/{id}/summary | Campaign summary |
GET | /reports/campaigns/{id}/aggregations | Campaign results over time |
GET | /reports/campaigns/{id}/action-details | Recipient actions |
GET | /reports/campaigns/{id}/recipients/{eventType} | Recipients by event type |
GET | /reports/campaigns/{id}/all-data-export | Full campaign report as ZIP |
GET | /reports/messages/summary | Message summary |
GET | /reports/messages/aggregations | Message results over time |
GET | /reports/messages/export | Message export as CSV |
Agents
GET /agents returns the active agents assigned to the account.
curl 'https://api.sare.pl/ext/rcs/v1/agents' \
-H 'Authorization: Bearer <integrationKey>:<secret>'Example response:
{
"items": [
{
"agentId": "google-rbm-agent-id",
"name": "Agent PL",
"displayName": "Brand",
"billingType": "single",
"active": true
}
]
}agentIdis the Google RBM Agent ID; pass it unchanged in messages and campaignsnameis the agent's technical namedisplayNameis the name displayed in SAREbillingTypespecifies the billing model:single,conversationalorbasic
Update an agent's display name and activity through PATCH /agents/{agentId}.
curl -X PATCH 'https://api.sare.pl/ext/rcs/v1/agents/google-rbm-agent-id' \
-H 'Authorization: Bearer <integrationKey>:<secret>' \
-H 'Content-Type: application/json' \
-d '{
"displayName": "New brand name",
"active": false
}'displayNameis optional and supports up to 31 characters- An empty string clears the display name
- The public API only accepts
falseforactive - The request must include at least one of
displayNameoractive
Message content
Message content can be supplied in two ways:
- Through an existing template:
{ "templateId": 55 }- Directly in the request as an inline message:
{
"inline": {
"type": "CARD",
"content": "Check out this week's offer.",
"buttons": [
{
"id": "offer-link",
"type": "url",
"text": "View offer",
"url": "https://example.com/oferta"
},
{
"id": "offer-interest",
"type": "quick_reply",
"text": "I am interested",
"payload": "OFFER_INTERESTED"
}
],
"data": {
"title": "Offer of the week",
"imageUrl": "https://example.com/images/offer.jpg",
"orientation": "VERTICAL",
"height": "TALL"
}
}
}Use only one option per request. Sending with templateId requires a template with APPROVED status.
Supported message types:
MESSAGEAUDIOVIDEOFILECARDCONTACTCAROUSELLOCATION
Public button types:
urlquick_replycallcalendarlocationtrigger_template
Every button must have an id unique across the entire message. For carousels, this rule applies across all cards. Media files and images must be available at public HTTPS URLs.
RCS Basic
Enable RCS Basic with basic: true.
- Only
MESSAGEtext is allowed - The message cannot contain buttons or media
- Maximum length is 160 UTF-8 bytes
- When using a template,
basicmust match in the template and the send request
Templates
New templates default to DRAFT. Only templates with APPROVED status can be used for sending.
curl -X POST 'https://api.sare.pl/ext/rcs/v1/templates' \
-H 'Authorization: Bearer <integrationKey>:<secret>' \
-H 'Content-Type: application/json' \
-d '{
"name": "Order status",
"description": "Parcel shipping notification",
"basic": false,
"status": "APPROVED",
"message": {
"type": "MESSAGE",
"content": "Your parcel has been shipped.",
"buttons": [],
"data": {}
}
}'nameis the template namedescriptionis an optional descriptionbasicselects RCS Basic modestatusdetermines whether the template is ready for sendingmessagecontains the message content
PUT /templates/{id} replaces the entire template, so supply all its data. A template cannot be deleted if it is used by a trigger_template button or an automatic reply configuration.
The template list supports pagination and filtering by status, type and creation date.
Transactional messages
POST /messages requires a unique Idempotency-Key header. Repeating an identical request with the same key does not create a second message. Using the same key with different content returns 409.
curl -X POST 'https://api.sare.pl/ext/rcs/v1/messages' \
-H 'Authorization: Bearer <integrationKey>:<secret>' \
-H 'Idempotency-Key: order-2026-000123' \
-H 'Content-Type: application/json' \
-d '{
"clientReferenceId": "order-2026-000123",
"agentId": "google-rbm-agent-id",
"recipient": "+48500100200",
"expiresAt": "2030-07-28T10:00:00.000Z",
"basic": false,
"message": { "templateId": 55 }
}'The API returns 202 and a messageId. Retrieve the current message state with GET /messages/{messageId}.
Typical message statuses:
ACCEPTEDSENDINGSENTDELIVEREDREADFAILEDEXPIRED
SMS fallback
The optional smsFallback field enables an SMS when RCS is unavailable for a number. smsFallbackAfterExpiry schedules an SMS after the RCS message expires.
{
"smsFallback": {
"planParams": {
"sender": "Brand",
"mode": "cut",
"campaign": "Order fallback 2026-000123",
"smsShipmentType": 1,
"sendTime": "2030-07-27T09:05:00.000Z",
"testNumbers": [],
"controlGroup": false,
"quarantine": false,
"useTestNumbers": false,
"consentIDS": [],
"ignoreStatus": false,
"delay": 0
},
"smsMessagesPlan": [
{
"content": "RCS is unavailable. Check your order status online.",
"multipart": false,
"diacriticalSigns": true,
"urlShortening": false,
"abTestDivision": 0
}
]
},
"smsFallbackAfterExpiry": {
"sendTime": "2030-07-28T10:30:00.000Z",
"delay": 0
}
}smsMessagesPlanmust contain exactly one message variant- Public fallback supports
smsShipmentType: 1 smsFallbackAfterExpiryrequires bothsmsFallbackandexpiresAtsmsFallbackAfterExpiry.sendTimemust be later thanexpiresAt
Test messages
POST /messages/test sends the same content to up to 5 unique numbers.
- Uses
recipientsinstead ofrecipient - Does not require an
Idempotency-Keyheader - Does not support SMS fallback
- Is excluded from transactional reports
Campaigns
A campaign uses existing SARE segments and requires an Idempotency-Key header, just like a transactional message.
curl -X POST 'https://api.sare.pl/ext/rcs/v1/campaigns' \
-H 'Authorization: Bearer <integrationKey>:<secret>' \
-H 'Idempotency-Key: campaign-2026-07-001' \
-H 'Content-Type: application/json' \
-d '{
"clientReferenceId": "campaign-2026-07-001",
"name": "Customer notification",
"agentId": "google-rbm-agent-id",
"segmentIds": [101, 102],
"scheduledAt": "2030-07-28T10:00:00.000Z",
"expiresAt": "2030-07-29T10:00:00.000Z",
"basic": false,
"message": { "templateId": 55 }
}'Key rules:
segmentIdsare SARE group identifiers shown asconfig.group, not technicalSegment.idrecords- The
campaignIdreturned byPOST /campaignsis the same identifier to use inGET /campaigns/{id}and reports - The backend saves a snapshot of template content when accepting the campaign
- Deleting a template does not change or cancel an already scheduled campaign
A campaign can contain smsFallback and smsFallbackAfterExpiry fields with the same structure as a transactional message.
smsFallback.planParams.sendTimemust be later thanscheduledAtsmsFallbackAfterExpiry.sendTimemust be later thanexpiresAt
Reports
Campaign reports provide:
- Send summary
- Results over time
- Recipient actions
- Recipient lists by event type
- Full data export in a ZIP archive
Transactional message reports include:
- Summary
- Daily aggregation
- CSV export
Messages sent through POST /messages/test are excluded from reports.
Restrict the reporting period with from and to parameters in YYYY-MM-DD format. List endpoints also support pagination and sorting.
curl 'https://api.sare.pl/ext/rcs/v1/reports/messages/summary?from=2030-07-01&to=2030-07-31' \
-H 'Authorization: Bearer <integrationKey>:<secret>'Webhooks
RCS webhook events, signature verification and example payloads are described on a separate page: RCS webhooks.
Errors
API errors include a stable business code and a requestId, which you should retain for technical support.
{
"statusCode": 400,
"code": "RCS_INVALID_MESSAGE",
"message": "RCS_INVALID_MESSAGE",
"requestId": "req_01J9ZQ6B7S1C2T"
}Common responses:
400- invalid data401- invalid credentials403- module unavailable404- resource not found409- conflict, such as reusing an idempotency key429- rate limit exceeded
Best practices
- Set a timeout for every request
- Retry
429and temporary5xxerrors with increasing delays - Do not automatically retry
4xxvalidation errors - Keep the same
Idempotency-Keywhen retrying - Store
messageId,campaignId,eventIdandrequestId - Send dates in ISO 8601 format, preferably UTC (
Z)