Skip to main content

RCS API (BETA) (1.0.0)

Download OpenAPI specification:Download

RCS API Description

The RCS API enables you to send rich, interactive messages using Google's RCS for Business platform. Send text messages, rich cards with images, carousels, and interactive suggestions to engage users with modern messaging experiences.

Core Concepts

  • RCS for Business: Google's rich communication services platform for businesses to send interactive messages to users.
  • RCS Agents: Verified business identities that send RCS messages. Each agent has a unique ID and branding.
  • Rich Content: Messages can include text, images, videos, rich cards, carousels, and interactive suggestions (buttons, replies, actions).
  • Webhooks: Receive real-time notifications for message delivery, read receipts, and user responses.

Key Features

  • Send rich text messages with formatting and emojis
  • Send standalone rich cards with images, titles, descriptions, and suggestions
  • Send carousel cards with multiple scrollable items
  • Add interactive suggestions (quick replies, URL actions, dial actions, calendar events, location sharing)
  • Receive delivery and read receipts via webhooks
  • Handle user responses and interactions
  • Multi-agent support for different use cases (notifications, conversations)

Basic Workflow

  1. Send RCS Message: Your application makes a POST request to the /rcs/v1/messages endpoint with the message content, recipient phone number, and agent ID.
  2. Message Delivery: The API forwards the message to Google RCS for Business, which delivers it to the recipient's RCS-enabled device.
  3. Receive Events: Your application receives webhook notifications for delivery status, read receipts, and user responses.

Suggested Actions

Suggestions attach interactive buttons to a message or card. Each suggestion is either a reply (sends text back to your webhook) or an action (opens a URL, dials a number, views a location, or creates a calendar event).

Open URL action

open_url_action opens a web page when the user taps the button. By default the link opens in the device's browser. You can instead open it inside an in-app webview, which keeps the user in the messaging app.

Field Required Description
url yes The URL to open.
application no BROWSER (device browser) or WEBVIEW (in-app webview). Defaults to the device browser when omitted.
webview_view_mode no Webview size: FULL, HALF, or TALL. Only honored when application is WEBVIEW.
description no Accessibility description of the action.

Open in the device browser (default):

{
  "action": {
    "text": "Open website",
    "postback_data": "open_site",
    "open_url_action": {
      "url": "https://www.spirius.com"
    }
  }
}

Open in an in-app webview:

{
  "action": {
    "text": "Open in app",
    "postback_data": "open_webview",
    "open_url_action": {
      "url": "https://www.spirius.com",
      "application": "WEBVIEW",
      "webview_view_mode": "HALF",
      "description": "Open spirius.com in a half-screen webview"
    }
  }
}

The API is lenient: unknown fields in a request are dropped rather than rejected. Use the exact snake_case field names above — a misspelled or unsupported field is silently ignored (and logged server-side), so the option simply has no effect. Webview support and view modes ultimately depend on the recipient's RCS client.

HTTP Response Codes

  • 200 OK: Successful GET requests (e.g., health checks).
  • 202 Accepted: Message accepted for delivery (async processing).
  • 400 Bad Request: Invalid request format, missing required fields, or validation errors.
  • 401 Unauthorized: Missing or invalid API key.
  • 403 Forbidden: Valid credentials but insufficient permissions, or invalid webhook signature.
  • 429 Too Many Requests: Rate limit exceeded (default: 100 requests/minute per client).
  • 500 Internal Server Error: Unexpected server error.
  • 501 Not Implemented: Requested feature not yet implemented (e.g., conversations agent).
  • 503 Service Unavailable: Service temporarily unavailable.

HTTP Headers

Authentication

The API uses dual-header authentication with API key and client ID:

X-API-Key: your_api_key_here
X-Client-ID: your_client_id
Content-Type: application/json

Example:

POST /rcs/v1/messages HTTP/1.1
Host: api.example.com
X-API-Key: rcs_live_abc123xyz
X-Client-ID: acme_corp
Content-Type: application/json

Limitations

Message Content

  • Text Messages: Up to 3072 characters
  • Rich Card Title: Up to 200 characters
  • Rich Card Description: Up to 2000 characters
  • Suggestions per Message: Maximum 4 suggestions per card, 11 per carousel
  • Carousel Cards: 2-10 cards per carousel

Rate Limits

  • Default: 100 requests per second per client
  • Scope: Limits applied per X-Client-ID
  • Exceeding the rate limit returns 429 Too Many Requests

Character Encoding

  • All request bodies must be UTF-8 encoded JSON
  • RCS supports full Unicode including emojis
  • Rich text formatting is supported (bold, italic, etc.)

Phone Number Format

Phone numbers must be in E.164 format:

  • Format: +[country_code][number]
  • Example: +46701234567 (Sweden), +12025551234 (USA)
  • Required: Leading + and country code
  • No spaces or special characters

Media Files

  • Images: JPEG, PNG (recommended max 2MB)
  • Videos: MP4, 3GP (recommended max 10MB)
  • Thumbnails: Automatically generated or provide custom URL
  • Hosting: Media files must be publicly accessible via HTTPS

RCS Events (Webhooks)

The API sends RCS Events to your configured webhook URL when users interact with your messages or when message status changes.

Event Types

Inbound (User Messages):

  • rcs.in.text: User sent a text message
  • rcs.in.file: User sent a file (image, video, document)
  • rcs.in.suggested.reply: User clicked a reply suggestion button
  • rcs.in.suggested.action: User clicked an action suggestion (URL, dial, location)

Outbound (Message Status):

  • rcs.out.delivered: Message successfully delivered to device
  • rcs.out.read: User opened/read the message
  • rcs.out.failed: Message failed to send

Subscription Events:

  • rcs.sub.subscribed: User subscribed via Google Messages UI
  • rcs.sub.unsubscribed: User unsubscribed (includes STOP words)

Test Events (Dry Run):

  • test.rcs.out.delivered: Simulated delivery event for testing

Complete Documentation

For complete webhook documentation including event payload structure, all field descriptions, example payloads, retry behavior, and integration guide, see the RCS Events section in the API reference.

Agent Types

The API supports multiple RBM agents for different use cases:

  • Notifications Agent: One-way messages (alerts, updates, confirmations)
  • Conversations Agent: Two-way conversations (customer support, inquiries)

Specify the agent using the agent_id field in your request.

Health

API health check endpoints.

API Liveness Check

Liveness check endpoint that verifies the API process is running.

This endpoint is used by Kubernetes liveness probes to determine if the pod should be restarted. It returns 200 as long as the process is alive.

Returns: HealthResponse: Status information indicating the API is alive

Responses

Response samples

Content type
application/json
{
  • "status": "string",
  • "message": "string"
}

API Readiness Check

Readiness check endpoint that verifies the API can handle requests.

This endpoint is used by Kubernetes readiness probes to determine if the pod should receive traffic. It checks critical dependencies:

  • Redis connection
  • PostgreSQL connection

Returns 200 only when all dependencies are available.

Returns: HealthResponse: Status information indicating the API is ready JSONResponse: 503 response if dependencies are not available

Responses

Response samples

Content type
application/json
{
  • "status": "string",
  • "message": "string"
}

RCS Events

Rcs Event Webhook Webhook

RCS Event Notification

The RCS API sends RCS Events to your configured webhook URL when users interact with your RCS messages or when message delivery status changes.

Event Types

Category Event Type Description Additional Info
Inbound rcs.in.text User sent a text message Freeform text from user
Inbound rcs.in.file User sent a file (image, video, document) Contains file URI and metadata
Inbound rcs.in.suggested.reply User clicked a reply suggestion button Quick reply in conversation
Inbound rcs.in.suggested.action User clicked an action suggestion Opens URL, dials phone, shares location, etc.
Outbound rcs.out.delivered Message successfully delivered to user's device Reliable delivery confirmation
Outbound rcs.out.read User opened and read the message Reliable read confirmation
Outbound rcs.out.failed Message failed to send When delivery fails due to error or network issue
Subscription rcs.sub.subscribed User subscribed via Google Messages UI or other channels User explicitly consents
Subscription rcs.sub.unsubscribed User unsubscribed via Google Messages UI, stop words, or other channels Must honor immediately
Test (Dry Run) test.rcs.out.delivered Simulated delivery event for testing One event per dry run message

Important Notes

  • Stop Words: When users send stop words (STOP, BAJA, parar, etc.) as text messages, they are mapped to rcs.sub.unsubscribed events. Your webhook may receive both the text message (rcs.in.text) and the unsubscribe event (rcs.sub.unsubscribed). Handle these idempotently.

Dry Run Testing

When sending messages with dry_run: true, no actual RCS message is sent. Instead, the API simulates the complete message flow and generates a test event to your webhook:

  • One test event is generated for each dry run message
  • test.rcs.out.delivered is sent (simulating successful delivery)
  • This event has the same structure as real events but with test.rcs.out. prefix
  • Use dry run mode to test your webhook integration without sending real messages

Webhook Configuration

Setting Value Notes
HTTP Method POST All webhook events are sent via POST
Content-Type application/json Event payload in JSON format
Authentication HMAC-SHA256 signature (always included) Signature sent in X-Webhook-Signature header - validation optional but recommended
Configuration Per-agent webhooks Use Webhook Management API to configure
Required Response HTTP 200-299 Any 2xx status code acknowledges receipt
Timeout 10 seconds Endpoint must respond within 10 seconds

Event Payload Fields

Field Type Description Always Present
event_type string Type of event (see Event Types table above) All events
agent_id string RBM agent identifier (e.g., 'spirius_notifications_agent') All events
send_time string Event timestamp in ISO 8601 format All events
event_id string Unique identifier for this specific event occurrence (format: evt_*) All events - use for deduplication
message_id string Message identifier linking events to their message For message-related events
client_message_id string Optional client-provided ID from original send request Only if provided by client
sender_phone_number string User's phone number in E.164 format When available
text string Plain text content of message For text messages
content_message object Structured message content (suggestion responses) For button clicks
user_file object File information (payload + thumbnail) For file uploads

Retry Behavior

Scenario Behavior
Successful Delivery (2xx response) No retries - event acknowledged
Failed Delivery (non-2xx, timeout, connection error) Automatic retry with exponential backoff
Retry Schedule Exponential backoff over several minutes
Maximum Attempts Multiple attempts before dead-letter queue
Duplicate Detection Same event may be delivered multiple times - use event_id to detect duplicates

Implementation Best Practices

  1. Respond immediately - Return HTTP 200-204 as soon as you receive the event
  2. Process asynchronously - Queue events for background processing
  3. Implement idempotency - Use event_id to detect and ignore duplicate deliveries
  4. Log failures - Track processing errors for manual review
  5. Monitor availability - Ensure your webhook endpoint is always accessible

Security & Authentication

HMAC Signature:

  • Every webhook event includes an X-Webhook-Signature header
  • Signature is HMAC-SHA256 hash of the request body using your webhook secret
  • Secret is auto-generated when you create the webhook (returned in response)
  • You can regenerate the secret anytime using the /regenerate-secret endpoint
  • Validation is optional - you can choose to validate or ignore the signature

Security Best Practices:

  1. Use HTTPS - Production webhooks must use HTTPS URLs
  2. Validate signatures (recommended) - Verify HMAC-SHA256 signature to ensure events are from Spirius
  3. Validate structure - Check event payload matches expected schema
  4. Respond quickly - Fast responses prevent unnecessary retries
  5. IP whitelisting - Consider restricting access to Spirius webhook sources

Python Signature Verification Example:

import hmac
import hashlib
from fastapi import FastAPI, Request, HTTPException, status

def verify_webhook_signature(payload_bytes: bytes, signature: str, secret: str) -> bool:
    '''
    Verify HMAC-SHA256 signature from X-Webhook-Signature header.
    
    Args:
        payload_bytes: Raw request body bytes
        signature: Value from X-Webhook-Signature header
        secret: Your webhook secret from webhook creation/regeneration
        
    Returns:
        True if signature is valid, False otherwise
    '''
    expected_signature = hmac.new(
        secret.encode('utf-8'),
        payload_bytes,
        hashlib.sha256
    ).hexdigest()
    
    # Use compare_digest to prevent timing attacks
    return hmac.compare_digest(expected_signature, signature)

# Example usage in FastAPI
app = FastAPI()

@app.post('/webhook')
async def webhook(request: Request):
    signature = request.headers.get('X-Webhook-Signature')
    payload_bytes = await request.body()
    
    # Validate signature (optional but recommended)
    if signature and not verify_webhook_signature(payload_bytes, signature, WEBHOOK_SECRET):
        raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail='Invalid signature')
    
    # Process event
    event = await request.json()
    # ... your business logic here ...
    
    return {'status': 'received'}

Note on Unsubscribe Events

When users unsubscribe, you may receive both an unsubscribe event AND a text message with a keyword (STOP, BAJA, parar, etc.). Ensure your system handles these idempotently to avoid duplicate processing.

Example Payloads

User Text Message

{
  "event_type": "rcs.in.text",
  "agent_id": "spirius_notifications_agent",
  "send_time": "2025-10-12T15:15:30.995131Z",
  "event_id": "evt_a1b2c3d4e5f678901234",
  "sender_phone_number": "+1234567890",
  "message_id": "550e8400-e29b-41d4-a716-446655440000",
  "text": "Hello, I have a question"
}

File Upload (User Sent Image/Document)

{
  "event_type": "rcs.in.file",
  "agent_id": "spirius_notifications_agent",
  "send_time": "2025-11-04T17:41:04.790512Z",
  "event_id": "evt_9f8e7d6c5b4a32109876",
  "sender_phone_number": "+34693363516",
  "message_id": "6ba7b810-9dad-11d1-80b4-00c04fd430c8",
  "user_file": {
    "payload": {
      "mime_type": "image/heic",
      "file_size_bytes": 910755,
      "file_name": "IMG_1644.heic",
      "file_uri": "https://rcs-copper-eu.googleapis.com/blob/..."
    },
    "thumbnail": {
      "mime_type": "image/jpeg",
      "file_size_bytes": 8249,
      "file_uri": "https://rcs-copper-eu.googleapis.com/blob/..."
    }
  }
}

Reply Suggestion (User Clicked Quick Reply)

{
  "event_type": "rcs.in.suggested.reply",
  "agent_id": "spirius_notifications_agent",
  "send_time": "2025-10-12T15:18:00.000000Z",
  "event_id": "evt_fedcba9876543210abcd",
  "sender_phone_number": "+1234567890",
  "message_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
  "content_message": {
    "suggestion_response": {
      "postback_data": "action_confirm",
      "text": "Confirm",
      "type": "REPLY"
    }
  }
}

Action Button (User Clicked Link/URL)

{
  "event_type": "rcs.in.suggested.action",
  "agent_id": "spirius_notifications_tggofuud_agent",
  "send_time": "2025-11-04T17:49:06.726341Z",
  "event_id": "evt_123456789abcdef01234",
  "sender_phone_number": "+34693363516",
  "message_id": "8ca1552a-b8a8-4068-bbf4-1046760224f4",
  "content_message": {
    "suggestion_response": {
      "postback_data": "book_nature_event",
      "text": "Book now",
      "type": "ACTION"
    }
  }
}

Message Delivered Event

{
  "event_type": "rcs.out.delivered",
  "agent_id": "spirius_notifications_agent",
  "send_time": "2025-10-12T15:16:00.123456Z",
  "sender_phone_number": "+1234567890",
  "event_id": "evt_d1e2f3a4b5c6d7e8f9a0",
  "message_id": "550e8400-e29b-41d4-a716-446655440000",
  "client_message_id": "client_msg_001",
  "create_time": "2025-10-12T15:16:00.123456Z"
}

Message Read Event

{
  "event_type": "rcs.out.read",
  "agent_id": "spirius_notifications_agent",
  "send_time": "2025-10-12T15:17:30.456789Z",
  "sender_phone_number": "+1234567890",
  "event_id": "evt_e1f2a3b4c5d6e7f8a9b0",
  "message_id": "550e8400-e29b-41d4-a716-446655440000",
  "client_message_id": "client_msg_001",
  "create_time": "2025-10-12T15:17:30.456789Z"
}

Message Failed Event

{
  "event_type": "rcs.out.failed",
  "agent_id": "spirius_notifications_agent",
  "send_time": "2025-10-12T15:18:00.000000Z",
  "event_id": "evt_f1a2b3c4d5e6f7a8b9c0",
  "message_id": "550e8400-e29b-41d4-a716-446655440000",
  "client_message_id": "client_msg_001",
  "create_time": "2025-10-12T15:18:00.000000Z"
}

User Subscribed Event (Google Messages UI)

{
  "event_type": "rcs.sub.subscribed",
  "agent_id": "spirius_notifications_agent",
  "send_time": "2025-10-12T15:21:00.000000Z",
  "event_id": "evt_1a2b3c4d5e6f7a8b9c0d",
  "create_time": "2025-10-12T15:21:00.000000Z"
}

User Unsubscribed Event (Google Messages UI)

{
  "event_type": "rcs.sub.unsubscribed",
  "agent_id": "spirius_notifications_agent",
  "send_time": "2025-10-12T15:20:00.000000Z",
  "event_id": "evt_2b3c4d5e6f7a8b9c0d1e",
  "create_time": "2025-10-12T15:20:00.000000Z"
}

Test Delivered Event (Dry Run Mode)

{
  "event_type": "test.rcs.out.delivered",
  "agent_id": "spirius_notifications_agent",
  "send_time": "2025-10-12T15:24:00.000000Z",
  "event_id": "evt_3c4d5e6f7a8b9c0d1e2f",
  "message_id": "9b2d5c8e-1234-4abc-9def-0123456789ab",
  "client_message_id": "client_msg_test_001",
  "create_time": "2025-10-12T15:24:00.000000Z"
}
Request Body schema: application/json
required
agent_id
required
string (Agent Id)

Agent identifier (e.g., 'spirius_notifications_agent')

send_time
required
string (Send Time)

Event send time (RFC3339)

Sender Phone Number (string) or Sender Phone Number (null) (Sender Phone Number)

User's phone number in E.164 format

Any of
string (Sender Phone Number)

User's phone number in E.164 format

Message Id (string) or Message Id (null) (Message Id)

Message identifier for tracking

Any of
string (Message Id)

Message identifier for tracking

Client Message Id (string) or Client Message Id (null) (Client Message Id)

Optional client-provided message ID from original request

Any of
string (Client Message Id)

Optional client-provided message ID from original request

Text (string) or Text (null) (Text)

Message text content

Any of
string (Text)

Message text content

ContentMessage (object) or null

Structured message content

Any of
Text (string) or Text (null) (Text)

Text content

SuggestionResponse (object) or null

Suggestion response

property name*
additional property
any
UserFile (object) or null

File uploaded by user (images, videos, documents)

Any of
required
object (FileInfo)

Main file information

FileInfo (object) or null

Thumbnail for images/videos

Event Type (string) or Event Type (null) (Event Type)

Event type (message.delivered, message.read, user.typing, etc.) - added outside model

Any of
string (Event Type)

Event type (message.delivered, message.read, user.typing, etc.) - added outside model

Event Id (string) or Event Id (null) (Event Id)

Unique Spirius event identifier for deduplication (format: evt_*) - present for all events

Any of
string (Event Id)

Unique Spirius event identifier for deduplication (format: evt_*) - present for all events

Create Time (string) or Create Time (null) (Create Time)

Event creation time (RFC3339)

Any of
string (Create Time)

Event creation time (RFC3339)

property name*
additional property
any

Responses

Request samples

Content type
application/json
{
  • "agent_id": "spirius_notifications_agent",
  • "event_id": "evt_a1b2c3d4e5f678901234",
  • "event_type": "rcs.in.text",
  • "message_id": "550e8400-e29b-41d4-a716-446655440000",
  • "send_time": "2025-10-12T15:15:30.995131Z",
  • "sender_phone_number": "+1234567890",
  • "text": "Hello, I have a question"
}

Response samples

Content type
application/json
null

RCS Messaging

Send Message

Send a rich RCS message asynchronously using a specific RBM agent.

This endpoint requires X-API-Key header authentication. It validates the request, publishes the message to a queue for async processing, and returns immediately. The actual RBM API call happens asynchronously in the worker service.

Async Processing:

  • Message is queued and processed asynchronously by the message worker
  • API returns immediately (< 50ms) with a message_id
  • Actual delivery happens within seconds via the worker

Message Tracking:

  • The message_id in the response is your tracking ID for this message
  • This ID will be included in all webhook events (delivery, read, user responses)
  • Optionally provide client_message_id to correlate with your own system
  • Both IDs will be included in webhook events for easy correlation
header Parameters
x-api-key
required
string (X-Api-Key)

API key for authentication

x-client-id
required
string (X-Client-Id)

Client ID for identification

Request Body schema: application/json
required
recipient
required
string (Recipient)

The user's phone number in E.164 format.

agent_id
required
string (Agent Id)

The RBM agent identifier.

required
object (rcs_api__models__rbm_message_models__ContentMessage)
Text (string) or Text (null) (Text)
ContentInfo (object) or null
RichCard (object) or null
Array of Suggestions (objects) or Suggestions (null) (Suggestions)
Message Traffic Type (string) or Message Traffic Type (null) (Message Traffic Type)

Traffic type to categorize the message. Defaults to agent's use case if not specified.

Any of
string (Message Traffic Type)
Enum: "AUTHENTICATION" "TRANSACTION" "PROMOTION" "SERVICEREQUEST" "ACKNOWLEDGEMENT" "MESSAGE_TRAFFIC_TYPE_UNSPECIFIED"

Traffic type to categorize the message. Defaults to agent's use case if not specified.

Client Message Id (string) or Client Message Id (null) (Client Message Id)

Optional client-provided message ID for tracking in your system. Will be included in webhook events.

Any of
<= 256 characters
string (Client Message Id) <= 256 characters

Optional client-provided message ID for tracking in your system. Will be included in webhook events.

dry_run
boolean (Dry Run)
Default: false

When true, simulates message sending without calling RBM API. Generates test.rcs.out.delivered events for integration testing.

Responses

Request samples

Content type
application/json
{
  • "recipient": "string",
  • "agent_id": "string",
  • "message": {
    },
  • "message_traffic_type": "AUTHENTICATION",
  • "client_message_id": "string",
  • "dry_run": false
}

Response samples

Content type
application/json
{
  • "message_id": "string",
  • "client_message_id": "string"
}

Tester Management

List Testers

List all testers for a specific agent.

This endpoint retrieves all test devices registered for the specified agent. Only testers associated with agents assigned to the authenticated client are accessible.

Query Parameters:

  • agent_id: Required. The agent ID to list testers for.

Returns:

  • 200 OK: List of testers
  • 401 Unauthorized: Invalid authentication
  • 403 Forbidden: Client not authorized for this agent
  • 502 Bad Gateway: Google API error
query Parameters
agent_id
required
string (Agent Id)

Agent ID to list testers for

header Parameters
x-api-key
required
string (X-Api-Key)

API key for authentication

x-client-id
required
string (X-Client-Id)

Client ID for identification

Responses

Response samples

Content type
application/json
{
  • "testers": [
    ],
  • "total_count": 0
}

Add Tester

Add a tester to an agent.

This endpoint registers a test device for the specified agent. The device owner will receive an invitation to become a tester.

Request Body:

  • phone_number: Phone number in E.164 format (e.g., +1234567890)
  • agent_id: Agent ID to add the tester to
  • label: Optional label for quick identification (e.g., 'János iOS')

Returns:

  • 200 OK: Tester created successfully
  • 400 Bad Request: Invalid request
  • 401 Unauthorized: Invalid authentication
  • 409 Conflict: Tester already exists
  • 502 Bad Gateway: Google API error
header Parameters
x-api-key
required
string (X-Api-Key)

API key for authentication

x-client-id
required
string (X-Client-Id)

Client ID for identification

Request Body schema: application/json
required
phone_number
required
string (Phone Number) ^\+[1-9]\d{1,14}$

Phone number in E.164 format (e.g., +1234567890)

agent_id
required
string (Agent Id)

Agent ID to add the tester to

Label (string) or Label (null) (Label)

Optional label for this tester (e.g., 'John iOS')

Any of
<= 25 characters
string (Label) <= 25 characters

Optional label for this tester (e.g., 'John iOS')

Responses

Request samples

Content type
application/json
{
  • "phone_number": "string",
  • "agent_id": "string",
  • "label": "string"
}

Response samples

Content type
application/json
{
  • "name": "string",
  • "phone_number": "string",
  • "agent_id": "string",
  • "invite_status": "string",
  • "label": "string"
}

Get Tester

Get a specific tester by phone number.

Query Parameters:

  • agent_id: Required. The agent ID.

Returns:

  • 200 OK: Tester information
  • 404 Not Found: Tester not found
  • 401 Unauthorized: Invalid authentication
  • 502 Bad Gateway: Google API error
path Parameters
phone_number
required
string (Phone Number)
query Parameters
agent_id
required
string (Agent Id)

Agent ID

header Parameters
x-api-key
required
string (X-Api-Key)

API key for authentication

x-client-id
required
string (X-Client-Id)

Client ID for identification

Responses

Response samples

Content type
application/json
{
  • "name": "string",
  • "phone_number": "string",
  • "agent_id": "string",
  • "invite_status": "string",
  • "label": "string"
}

Update Tester

Update a tester's Spirius-specific fields.

This endpoint updates only the label field. All RBM fields are synced automatically from Google's API to ensure consistency.

Query Parameters:

  • agent_id: Required. The agent ID.

Request Body:

  • label: Updated label (can be null to clear, max 25 chars)

Returns:

  • 200 OK: Tester updated successfully
  • 404 Not Found: Tester not found
  • 401 Unauthorized: Invalid authentication
  • 502 Bad Gateway: Google API error
path Parameters
phone_number
required
string (Phone Number)
query Parameters
agent_id
required
string (Agent Id)

Agent ID

header Parameters
x-api-key
required
string (X-Api-Key)

API key for authentication

x-client-id
required
string (X-Client-Id)

Client ID for identification

Request Body schema: application/json
required
Label (string) or Label (null) (Label)

Updated label for this tester (e.g., 'John iOS')

Any of
<= 25 characters
string (Label) <= 25 characters

Updated label for this tester (e.g., 'John iOS')

Responses

Request samples

Content type
application/json
{
  • "label": "string"
}

Response samples

Content type
application/json
{
  • "name": "string",
  • "phone_number": "string",
  • "agent_id": "string",
  • "invite_status": "string",
  • "label": "string"
}

Remove Tester

Remove a tester from an agent.

This endpoint removes a test device registration from the specified agent.

Query Parameters:

  • agent_id: Required. The agent ID.

Returns:

  • 204 No Content: Tester removed successfully
  • 404 Not Found: Tester not found
  • 401 Unauthorized: Invalid authentication
  • 502 Bad Gateway: Google API error
path Parameters
phone_number
required
string (Phone Number)
query Parameters
agent_id
required
string (Agent Id)

Agent ID

header Parameters
x-api-key
required
string (X-Api-Key)

API key for authentication

x-client-id
required
string (X-Client-Id)

Client ID for identification

Responses

Response samples

Content type
application/json
{
  • "detail": [
    ]
}

Device Capabilities

Check device RCS capability

Check if a phone number supports RCS messaging and retrieve supported features.

**Caching Strategy:**
- Results are cached globally (shared across all clients)
- RCS-supported devices: 7 day cache TTL
- Non-RCS devices: 24 hour cache TTL
- Use `force_refresh=true` to bypass cache

**Use Cases:**
- Pre-send capability check for campaign planning
- Testing specific devices during development
- Integration workflows that route based on capability

**Note:** When sending messages via `/messages`, capability checking happens 
automatically in the background - you don't need to call this endpoint explicitly 
for every message send.
path Parameters
phone
required
string (Phone)
Examples: +1234567890

Phone number in E.164 format (e.g., +1234567890)

query Parameters
agent_id
required
string (Agent Id)
Examples: agent_id=notifications

RBM agent ID to use for capability check

force_refresh
boolean (Force Refresh)
Default: false

Force fresh capability check, bypassing cache. Useful for testing.

header Parameters
x-api-key
required
string (X-Api-Key)

API key for authentication

x-client-id
required
string (X-Client-Id)

Client ID for identification

Responses

Response samples

Content type
application/json
{
  • "phone_number": "+1234567890",
  • "rcs_supported": true,
  • "features": [
    ],
  • "checked_at": "2025-10-13T10:30:00Z",
  • "cached": true
}

Webhook Management

Create webhook configuration

Register a new webhook to receive RCS events for a specific agent.

**Security:**
- Webhook secret is automatically generated server-side (64-char hex)
- Secret is returned in response - store it securely for HMAC verification
- HTTPS required in production environments

**Event Filtering:**
- Use `enabled_events` to subscribe to specific event types
- Default: `["*"]` receives all events (broadcast pattern)
- Multiple webhooks per agent supported - events broadcast to ALL matching webhooks

**Available Event Types:**
- `"*"` - All events (wildcard)

Inbound (user messages):
- `"rcs.in.text"` - User sent a text message
- `"rcs.in.file"` - User sent a file (image, video, document)
- `"rcs.in.suggested.reply"` - User clicked a reply suggestion button
- `"rcs.in.suggested.action"` - User clicked an action suggestion (URL, dial, location)

Outbound (message status):
- `"rcs.out.delivered"` - Message delivered to user's device
- `"rcs.out.read"` - User opened and read the message
- `"rcs.out.failed"` - Message failed to send

Subscription:
- `"rcs.sub.subscribed"` - User subscribed via Google Messages
- `"rcs.sub.unsubscribed"` - User unsubscribed (includes STOP words)

**Example Filters:**
- `["*"]` - Receive all events
- `["rcs.out.delivered", "rcs.out.failed"]` - Only delivery status
- `["rcs.sub.unsubscribed"]` - Only unsubscribe events
- `["rcs.in.text", "rcs.in.suggested.reply"]` - Only inbound messages
- `["rcs.out.delivered", "rcs.out.read"]` - Message engagement tracking

**Event Delivery:**
- Events are signed with HMAC-SHA256 using the webhook secret
- Set `is_enabled: false` to create in disabled state (optional, defaults to true)
- Add `description` for organizational purposes (optional)

**Constraints:**
- Maximum 5 webhooks per agent
- Cannot create duplicate (agent_id + webhook_url) combination
- Returns 409 Conflict if same URL already registered for agent
- Returns 400 Bad Request if webhook limit exceeded

**Verification:**
- Use `POST /v1/webhooks/{id}/test` to verify webhook is working
header Parameters
x-api-key
required
string (X-Api-Key)

API key for authentication

x-client-id
required
string (X-Client-Id)

Client ID for identification

Request Body schema: application/json
required
agent_id
required
string (Agent Id) [ 1 .. 100 ] characters

Agent identifier for this webhook

webhook_url
required
string <uri> (Webhook Url) [ 1 .. 2083 ] characters

Webhook URL to receive events

is_enabled
boolean (Is Enabled)
Default: true

Whether webhook is enabled

enabled_events
Array of strings (Enabled Events)
Default: ["*"]

Event types to receive. Use ['*'] for all events, or specify individual event types

Description (string) or Description (null) (Description)

Optional description for organizational purposes

Any of
<= 255 characters
string (Description) <= 255 characters

Optional description for organizational purposes

Responses

Request samples

Content type
application/json
{
  • "agent_id": "string",
  • "webhook_url": "http://example.com",
  • "is_enabled": true,
  • "enabled_events": [
    ],
  • "description": "string"
}

Response samples

Content type
application/json
{
  • "id": "550e8400-e29b-41d4-a716-446655440000",
  • "agent_id": "spirius-notifications",
  • "webhook_secret": "whsec_a1b2c3d4e5f6...",
  • "is_enabled": true,
  • "enabled_events": [
    ],
  • "description": "Production webhook for all events",
  • "created_at": "2024-01-15T10:30:00Z",
  • "updated_at": "2024-01-15T10:30:00Z"
}

List webhooks for an agent

List all webhook configurations for a specific agent.

**Multiple Webhooks Pattern:**
- An agent can have multiple webhook endpoints
- Events are broadcast to ALL enabled webhooks that match the event filter
- Use `enabled_events` to control which webhooks receive which events

**Use Cases:**
- Separate endpoints for different services (analytics, CRM, compliance)
- Testing webhooks alongside production webhooks
- Third-party integrations (e.g., Segment, Customer.io)
query Parameters
agent_id
required
string (Agent Id)
header Parameters
x-api-key
required
string (X-Api-Key)

API key for authentication

x-client-id
required
string (X-Client-Id)

Client ID for identification

Responses

Response samples

Content type
application/json
[
  • {
    },
  • {
    }
]

Get webhook configuration

Retrieve a specific webhook configuration by ID.

**Note:** Webhooks are agent-owned. Any authenticated client can view any webhook.
path Parameters
webhook_id
required
string <uuid> (Webhook Id)

Webhook ID

header Parameters
x-api-key
required
string (X-Api-Key)

API key for authentication

x-client-id
required
string (X-Client-Id)

Client ID for identification

Responses

Response samples

Content type
application/json
{
  • "id": "550e8400-e29b-41d4-a716-446655440000",
  • "agent_id": "spirius-notifications",
  • "webhook_secret": "whsec_a1b2c3...",
  • "is_enabled": true,
  • "created_at": "2024-01-15T10:30:00Z",
  • "updated_at": "2024-01-15T10:30:00Z"
}

Update webhook configuration

Update webhook configuration (partial update).

**Updatable fields:**
- `webhook_url`: Change webhook endpoint URL
- `is_enabled`: Enable or disable webhook temporarily
- `enabled_events`: Change event subscription
- `description`: Update organizational description

**Available Event Types for `enabled_events`:**
- `"*"` - All events (wildcard)
- `"message.sent"` - User sent a message or clicked a button
- `"message.delivered"` - Message delivered to device
- `"message.read"` - User read the message
- `"message.failed"` - Message failed to send
- `"user.typing"` - User is typing
- `"user.subscribed"` - User subscribed via Google Messages
- `"user.unsubscribed"` - User unsubscribed via Google Messages
- `"user.opted_in"` - User opted in via API/other channels
- `"user.opted_out"` - User opted out via API/other channels

**Immutable fields:**
- `agent_id`: Cannot be changed (delete and recreate instead)
- `webhook_secret`: Cannot be updated (use regenerate-secret endpoint)

**All fields are optional** - only provide fields you want to update.
path Parameters
webhook_id
required
string <uuid> (Webhook Id)

Webhook ID

header Parameters
x-api-key
required
string (X-Api-Key)

API key for authentication

x-client-id
required
string (X-Client-Id)

Client ID for identification

Request Body schema: application/json
required
Webhook Url (string) or Webhook Url (null) (Webhook Url)

New webhook URL

Any of
[ 1 .. 2083 ] characters
string <uri> (Webhook Url) [ 1 .. 2083 ] characters

New webhook URL

Is Enabled (boolean) or Is Enabled (null) (Is Enabled)

Whether webhook is enabled

Any of
boolean (Is Enabled)

Whether webhook is enabled

Array of Enabled Events (strings) or Enabled Events (null) (Enabled Events)

Event types to receive

Any of
Array
string
Description (string) or Description (null) (Description)

Webhook description

Any of
<= 255 characters
string (Description) <= 255 characters

Webhook description

Responses

Request samples

Content type
application/json
{
  • "webhook_url": "http://example.com",
  • "is_enabled": true,
  • "enabled_events": [
    ],
  • "description": "string"
}

Response samples

Content type
application/json
{
  • "id": "550e8400-e29b-41d4-a716-446655440000",
  • "agent_id": "spirius-notifications",
  • "webhook_secret": "whsec_a1b2c3...",
  • "is_enabled": false,
  • "created_at": "2024-01-15T10:30:00Z",
  • "updated_at": "2024-01-15T16:45:00Z"
}

Delete webhook configuration

Permanently delete a webhook configuration.

**⚠️ Warning:**
- Deletion is permanent and cannot be undone
- All event delivery to this webhook will stop immediately
- Consider disabling instead (`is_enabled: false`) for temporary pause

**Alternative:** Use `PATCH /v1/webhooks/{id}` with `is_enabled: false` 
to temporarily disable without losing configuration.
path Parameters
webhook_id
required
string <uuid> (Webhook Id)

Webhook ID

header Parameters
x-api-key
required
string (X-Api-Key)

API key for authentication

x-client-id
required
string (X-Client-Id)

Client ID for identification

Responses

Response samples

Content type
application/json
{
  • "detail": "Webhook 550e8400-e29b-41d4-a716-446655440000 not found"
}

Regenerate webhook secret

Generate a new webhook secret (secret rotation).

**Use cases:**
- Secret compromised or exposed
- Periodic security policy (rotate every 90 days)
- Initial deployment mistake

**⚠️ Important:**
- Old secret is immediately invalidated
- Update your webhook verification code before events arrive
- Test webhook after regeneration to confirm new secret works

**Process:**
1. Call this endpoint to get new secret
2. Update your webhook handler to verify with new secret
3. Test webhook with `POST /v1/webhooks/{id}/test`
path Parameters
webhook_id
required
string <uuid> (Webhook Id)

Webhook ID

header Parameters
x-api-key
required
string (X-Api-Key)

API key for authentication

x-client-id
required
string (X-Client-Id)

Client ID for identification

Responses

Response samples

Content type
application/json
{
  • "id": "550e8400-e29b-41d4-a716-446655440000",
  • "webhook_secret": "whsec_x7y8z9...",
  • "regenerated_at": "2024-01-20T09:15:00Z"
}

Enable webhook

Enable a webhook to resume receiving events.

path Parameters
webhook_id
required
string <uuid> (Webhook Id)

Webhook ID

header Parameters
x-api-key
required
string (X-Api-Key)

API key for authentication

x-client-id
required
string (X-Client-Id)

Client ID for identification

Responses

Response samples

Content type
application/json
{
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "agent_id": "string",
  • "webhook_url": "string",
  • "webhook_secret": "string",
  • "is_enabled": true,
  • "enabled_events": [
    ],
  • "description": "string",
  • "created_at": "2019-08-24T14:15:22Z",
  • "updated_at": "2019-08-24T14:15:22Z"
}

Disable webhook

Disable a webhook to temporarily stop receiving events without deleting the configuration.

path Parameters
webhook_id
required
string <uuid> (Webhook Id)

Webhook ID

header Parameters
x-api-key
required
string (X-Api-Key)

API key for authentication

x-client-id
required
string (X-Client-Id)

Client ID for identification

Responses

Response samples

Content type
application/json
{
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "agent_id": "string",
  • "webhook_url": "string",
  • "webhook_secret": "string",
  • "is_enabled": true,
  • "enabled_events": [
    ],
  • "description": "string",
  • "created_at": "2019-08-24T14:15:22Z",
  • "updated_at": "2019-08-24T14:15:22Z"
}

Test webhook endpoint

Send a test event to the webhook URL to verify it's working correctly.

**What it does:**
- Sends a test event with `event_type: "webhook.test"`
- Measures response time
- Validates webhook endpoint is reachable

**Use cases:**
- Verify webhook after initial setup
- Test after URL change
- Confirm webhook after secret regeneration
- Troubleshoot delivery issues

**Test event format:**
```json
{
    "event_type": "webhook.test",
    "timestamp": "2024-01-15T10:30:00Z",
    "webhook_id": "550e8400-e29b-41d4-a716-446655440000",
    "agent_id": "spirius-notifications",
    "message": "This is a test event from Spirius RCS API"
}
```

**Success criteria:**
- Webhook returns 200, 201, 202, or 204
- Response received within 10 seconds
path Parameters
webhook_id
required
string <uuid> (Webhook Id)

Webhook ID

header Parameters
x-api-key
required
string (X-Api-Key)

API key for authentication

x-client-id
required
string (X-Client-Id)

Client ID for identification

Responses

Response samples

Content type
application/json
Example
{
  • "success": true,
  • "status_code": 200,
  • "response_time_ms": 145,
  • "test_event_sent": {
    }
}