GET /v1/triggers/new-message-received
Most recent inbound messages from your contacts, used by polling integrations like n8n and Zapier.
Returns up to 100 most-recent inbound messages for the tenant, sorted by created_at DESC. This is the polling source for n8n's Qyvo trigger node and equivalent integrations.
GET /api/v1/triggers/new-message-received
Query parameters
| Param | Type | Description |
|---|---|---|
message_type |
string | Optional. Filter by text, image, audio, document, video, location, contacts, interactive |
Request
curl 'https://www.qyvo.io/api/v1/triggers/new-message-received?message_type=text' \
-H "Authorization: Bearer YOUR_TOKEN_HERE"
const messages = await fetch(
'https://www.qyvo.io/api/v1/triggers/new-message-received?message_type=text',
{ headers: { Authorization: `Bearer ${process.env.QYVO_TOKEN}` } },
).then((r) => r.json());
$messages = Http::withToken(env('QYVO_TOKEN'))
->get('https://www.qyvo.io/api/v1/triggers/new-message-received', [
'message_type' => 'text',
])
->json();
import os, httpx
messages = httpx.get(
'https://www.qyvo.io/api/v1/triggers/new-message-received',
params={'message_type': 'text'},
headers={'Authorization': f"Bearer {os.environ['QYVO_TOKEN']}"},
).json()
Response — 200 OK
An array (not an envelope). Empty [] when there are no messages.
[
{
"id": "01J4M...",
"direction": "inbound",
"type": "text",
"content": { "body": "Hi, do you ship to Canada?" },
"status": "received",
"contact_id": "01J1Y...",
"contact_phone": "+14155550123",
"contact_name": "Romain",
"contact_email": null,
"sent_at": null,
"delivered_at": null,
"read_at": null,
"created_at": "2026-05-07T08:14:23+00:00"
}
]
| Field | Type | Notes |
|---|---|---|
id |
UUID | Qyvo message id |
direction |
string | Always inbound |
type |
string | text, image, audio, … |
content |
object | Shape depends on type — {body} for text, {url, mime_type} for media |
status |
string | received for normal inbound; never sent/delivered/read (those apply to outbound) |
contact_* |
various | Denormalized fields from the joined contact |
created_at |
ISO 8601 | Server insertion time — the field you compare for new-since-last-poll |
Polling pattern
Remember the most recent id you've processed. On the next poll, stop iterating when you hit it. See Pagination for the canonical pattern.
Webhook alternative
If you can receive HTTPS callbacks, use the message.received webhook instead — same payload, no polling.
