Search conversations
Search your conversations two ways at once, and get back the matching conversations, most-recent match first:
- Message text: matches words inside message bodies. Case-insensitive and accent-insensitive, exact tokens only (no substrings, no stemming). Each hit carries up to 3 most-recent matching messages. With direction=outgoing you can collect examples of how you write to customers, for example to teach an AI agent your tone of voice.
- Contact identity: matches the participant's name, username, or phone number as a case-insensitive substring. These hits have matchCount 0 and an empty matches array.
A conversation that matches both ways is returned once, carrying its message matches.
Only platforms whose messages are stored by Zernio are searchable: WhatsApp, SMS, Telegram, Facebook, Instagram, Twitter/X and Reddit. Bluesky conversations are fetched live from the platform and cannot be searched; those accounts are listed in meta.accountsSkipped.
API key authentication - use your Zernio API key as a Bearer token
In: header
Query Parameters
Text to search for, in message content and in the contact's name, username, or phone number
2 <= length <= 200Only match messages sent to you (incoming) or by you (outgoing). Contact-identity matching is not applied when this is set.
"incoming" | "outgoing"Filter by profile ID
Filter by platform (searchable platforms only)
"facebook" | "instagram" | "telegram" | "whatsapp" | "sms"Filter by specific social account ID
Maximum number of conversations to return
201 <= value <= 50Pagination cursor for next page
Response Body
application/json
application/json
import Zernio from '@zernio/node';const zernio = new Zernio({ apiKey: process.env.ZERNIO_API_KEY });const { data } = await zernio.messages.searchInboxConversations({ query: { query: 'string', },});console.log(data);{
"data": [
{
"conversation": {
"id": "string",
"platform": "string",
"accountId": "string",
"participantName": "string",
"participantUsername": "string",
"participantPicture": "string",
"status": "active",
"lastMessage": "string",
"lastMessageAt": "2019-08-24T14:15:22Z"
},
"matchCount": 0,
"matches": [
{
"id": "string",
"text": "string",
"direction": "incoming",
"timestamp": "2019-08-24T14:15:22Z"
}
]
}
],
"pagination": {
"hasMore": true,
"nextCursor": "string"
},
"meta": {
"accountsQueried": 0,
"accountsFailed": 0,
"failedAccounts": [
{
"accountId": "string",
"accountUsername": "string",
"platform": "string",
"error": "string"
}
],
"lastUpdated": "2019-08-24T14:15:22Z",
"accountsSkipped": [
{
"accountId": "string",
"platform": "string"
}
]
}
}{
"error": "Unauthorized"
}List conversations GET
Fetch conversations (DMs) from all connected messaging accounts in a single API call. Supports filtering by profile and platform. Results are aggregated and deduplicated. Supported platforms: Facebook, Instagram, Twitter/X, Bluesky, Reddit, Telegram. Twitter/X limitation: X has replaced traditional DMs with encrypted "X Chat" for many accounts. Messages sent or received through encrypted X Chat are not accessible via X's API (the /2/dm_events endpoint only returns legacy unencrypted DMs). This means some Twitter/X conversations may show only outgoing messages or appear empty. This is an X platform limitation that affects all third-party applications. See X's docs on encrypted messaging for more details.
Create conversation POST
Initiate a new direct message conversation with a specified user. If a conversation already exists with the recipient, the message is added to the existing thread. Supported platforms: X/Twitter, Bluesky, Reddit, and WhatsApp. Other platforms return PLATFORM_NOT_SUPPORTED. WhatsApp: this is the endpoint for sending an approved template message to a phone number. Provide templateName, templateLanguage, and templateParams (variable values for the text header, body and dynamic URL buttons, in that order), with the recipient phone in participantId. A template is required because WhatsApp does not permit freeform messages to open a conversation; a missing template returns TEMPLATE_REQUIRED. Templates with media headers (image, video, document) are handled automatically: Zernio reads the approved template definition and fills the header at send time with the template's approved sample asset. To send a DIFFERENT asset per message (e.g. a distinct invoice PDF for each recipient), pass the headerMedia field with a public link (or a Meta media id); it overrides the sample for that send. Calling this for a number you already have a thread with simply sends the template into that thread, which also makes it the way to re-engage a contact after the 24-hour customer-service window has closed. Once the recipient replies (opening the 24h window), send freeform messages with the send-message endpoint (POST /v1/inbox/conversations/{conversationId}/messages). Template fields are accepted on the JSON body only, not on multipart requests. DM eligibility (X/Twitter): Before sending, the endpoint checks if the recipient accepts DMs from your account (via the receives_your_dm field). If not, a 422 error with code DM_NOT_ALLOWED is returned. You can skip this check with skipDmCheck: true if you have already verified eligibility. X API tier requirement: DM write endpoints require X API Pro tier ($5,000/month) or Enterprise access. This applies to BYOK (Bring Your Own Key) users who provide their own X API credentials. Rate limits (X/Twitter only): X's DM API enforces 200 requests per 15 minutes, 1,000 per 24 hours per connected X account, and 15,000 per 24 hours per X developer app (shared across all DM endpoints). These limits do NOT apply to other platforms. WhatsApp sends are governed by Meta's per-number messaging tiers (unique business-initiated conversations per 24 hours) and per-number throughput instead.