RCSZilla Version 1.0

Incoming Messages API

Read received SMS, WhatsApp, and Email messages via the REST API.

Overview

These endpoints let you pull incoming messages that RCSZilla has received — SMS and WhatsApp via Android devices, and Email via IMAP polling. Use them for batch reads, syncing to a CRM, or as a fallback alongside webhooks.

EndpointMethodDescription
incoming_messagesGETList received SMS and WhatsApp messages.
incoming_emailsGETList received emails from IMAP-polled inboxes.
*
For efficient polling, use after_id instead of date ranges. Store the highest id from the last response and pass it on the next call — you will only get new messages, no duplicates, no gaps.

List Incoming SMS / WhatsApp

GET /?endpoint=incoming_messages

Returns a paginated list of SMS and WhatsApp messages received by your Android devices. Includes matched contact info and device details.

Query Parameters

FieldTypeDescription
sincestring optional ISO 8601 datetime. Only messages received at or after this time.
untilstring optional ISO 8601 datetime. Only messages received at or before this time.
channelstring optional Filter by channel: sms or whatsapp.
device_idint optional Filter by device ID.
from_phonestring optional Filter by sender phone number (exact match).
after_idint optional Only return messages with ID greater than this value. Ideal for incremental polling.
limitint optional Results per page (1–100). Default: 50.
offsetint optional Pagination offset. Default: 0.

Example Request

curl "https://api.rcszilla.com/?endpoint=incoming_messages&after_id=208&limit=50" \
  -H "Authorization: Bearer YOUR-API-TOKEN"
curl "https://api.rcszilla.com/?endpoint=incoming_messages&since=2026-05-27T00:00:00Z&channel=sms&limit=20" \
  -H "Authorization: Bearer YOUR-API-TOKEN"
curl "https://api.rcszilla.com/?endpoint=incoming_messages&from_phone=%2B40712345678&limit=10" \
  -H "Authorization: Bearer YOUR-API-TOKEN"

Response

JSON
{
  "success": true,
  "total": 142,
  "limit": 50,
  "offset": 0,
  "messages": [
    {
      "id": 209,
      "channel": "sms",
      "from_phone": "+40712345678",
      "message": "Yes, I want to book an appointment for Monday",
      "received_at": "2026-05-27 14:30:05",
      "contact": {
        "id": 42,
        "name": "John Doe",
        "phone": "+40712345678"
      },
      "device": {
        "id": 6,
        "name": "Office Samsung"
      }
    },
    {
      "id": 208,
      "channel": "whatsapp",
      "from_phone": "+40798765432",
      "message": "Hello, do you have availability this week?",
      "received_at": "2026-05-27 14:25:12",
      "contact": null,
      "device": {
        "id": 6,
        "name": "Office Samsung"
      }
    }
  ]
}

Response Fields

FieldTypeDescription
idintUnique message ID. Use the highest value as after_id for incremental polling.
channelstringsms or whatsapp
from_phonestringSender phone number.
messagestringMessage text.
received_atstringWhen the message was received.
contactobject|nullMatched contact (id, name, phone) or null if sender is unknown.
deviceobject|nullDevice that received the message (id, name).

List Incoming Emails

GET /?endpoint=incoming_emails

Returns a paginated list of emails received by IMAP-polled inboxes linked to your SMTP servers. Includes both plain-text and HTML body.

Query Parameters

FieldTypeDescription
sincestring optional ISO 8601 datetime. Only messages received at or after this time.
untilstring optional ISO 8601 datetime. Only messages received at or before this time.
smtp_server_idint optional Filter by SMTP/IMAP server ID.
from_emailstring optional Filter by sender email address (exact match).
searchstring optional Search in subject, from_email, and from_name (partial match).
after_idint optional Only return messages with ID greater than this value. Ideal for incremental polling.
limitint optional Results per page (1–100). Default: 50.
offsetint optional Pagination offset. Default: 0.

Example Request

curl "https://api.rcszilla.com/?endpoint=incoming_emails&after_id=309&limit=20" \
  -H "Authorization: Bearer YOUR-API-TOKEN"
curl "https://api.rcszilla.com/?endpoint=incoming_emails&search=order&since=2026-05-01T00:00:00Z" \
  -H "Authorization: Bearer YOUR-API-TOKEN"

Response

JSON
{
  "success": true,
  "total": 38,
  "limit": 20,
  "offset": 0,
  "emails": [
    {
      "id": 310,
      "from_email": "customer@example.com",
      "from_name": "John Doe",
      "to_email": "support@yourbusiness.com",
      "subject": "Re: Your order #1234",
      "body_text": "Hi, when will my order arrive?\n\nThanks,\nJohn",
      "body_html": "<p>Hi, when will my order arrive?</p>",
      "message_id": "<abc123@mail.example.com>",
      "received_at": "2026-05-27 14:28:00",
      "created_at": "2026-05-27 14:30:02",
      "server": {
        "id": 5,
        "label": "Support Mailbox"
      }
    }
  ]
}

Response Fields

FieldTypeDescription
idintUnique email ID. Use the highest value as after_id for incremental polling.
from_emailstringSender email address.
from_namestringSender display name.
to_emailstringRecipient address (your mailbox).
subjectstringEmail subject line.
body_textstringPlain-text body.
body_htmlstringHTML body (may be empty if the email was plain-text only).
message_idstringEmail Message-ID header (for threading / deduplication).
received_atstringWhen the message was received.
serverobjectSMTP/IMAP server that received this email (id, label).

Recommended Polling Pattern

The most efficient way to read new messages is the after_id cursor pattern. Here is a complete example:

PHP
<?php
$token   = 'YOUR_API_TOKEN';
$api     = 'https://api.rcszilla.com';
$last_id = (int) file_get_contents('/tmp/last_sms_id.txt') ?: 0;

$url  = "$api/?endpoint=incoming_messages&after_id=$last_id&limit=100";
$resp = json_decode(file_get_contents($url, false, stream_context_create([
    'http' => ['header' => "Authorization: Bearer $token"]
])), true);

foreach ($resp['messages'] as $msg) {
    echo "[{$msg['channel']}] {$msg['from_phone']}: {$msg['message']}\n";
    if ((int)$msg['id'] > $last_id) $last_id = (int)$msg['id'];
}

file_put_contents('/tmp/last_sms_id.txt', $last_id);
Node.js
const fs = require('fs');
const TOKEN = 'YOUR_API_TOKEN';
const API   = 'https://api.rcszilla.com';

let lastId = 0;
try { lastId = parseInt(fs.readFileSync('/tmp/last_sms_id.txt', 'utf8')) || 0; } catch {}

const url = `${API}/?endpoint=incoming_messages&after_id=${lastId}&limit=100`;
const resp = await fetch(url, { headers: { Authorization: `Bearer ${TOKEN}` } });
const data = await resp.json();

for (const msg of data.messages) {
  console.log(`[${msg.channel}] ${msg.from_phone}: ${msg.message}`);
  if (msg.id > lastId) lastId = msg.id;
}

fs.writeFileSync('/tmp/last_sms_id.txt', String(lastId));
Python
import requests, pathlib

TOKEN = 'YOUR_API_TOKEN'
API   = 'https://api.rcszilla.com'
STATE = pathlib.Path('/tmp/last_sms_id.txt')

last_id = int(STATE.read_text()) if STATE.exists() else 0
resp = requests.get(f'{API}/?endpoint=incoming_messages&after_id={last_id}&limit=100',
                    headers={'Authorization': f'Bearer {TOKEN}'}).json()

for msg in resp['messages']:
    print(f"[{msg['channel']}] {msg['from_phone']}: {msg['message']}")
    last_id = max(last_id, msg['id'])

STATE.write_text(str(last_id))
*
For real-time delivery instead of polling, configure a Webhook. You can use both: webhooks for instant notification and the API for batch reads or recovery after downtime.