Logs API
Every send the campaign has made, with delivery state and Telegram-side message IDs.
The logs endpoint exposes a flat, time-ordered stream of outbound messages for a campaign. Inbound messages that triggered an auto-reply are referenced via triggered_by_message_id so you can stitch a conversation back together without a second call.
List logs
GET /api/v1/campaigns/{id}/logs — requires logs:read.
curl "https://prime-bot.live/api/v1/campaigns/1/logs?status=sent&per_page=100" \
-H "Authorization: Bearer $TOKEN"
Query parameters
| Name | Default | Description |
|---|---|---|
per_page | 25 | Page size, capped at 200. |
page | 1 | 1-indexed page number. |
status | (none) | sent, failed, or pending. |
since | (none) | ISO 8601 timestamp. Only logs strictly after this are returned. |
sender_id | (none) | Filter to a single contact's conversation. |
Response shape
{
"data": [
{
"id": 88212,
"campaign_id": 1,
"sender_id": 904,
"direction": "outbound",
"body": "Hey Jane, happy to send pricing over.",
"status": "sent",
"telegram_message_id": "1827361234",
"triggered_by_message_id": "1827361231",
"sequence_step": 0,
"error": null,
"sent_at": "2026-04-21T16:02:45Z",
"created_at": "2026-04-21T16:02:42Z"
}
],
"meta": {
"pagination": {
"current_page": 1,
"per_page": 100,
"total": 1243,
"last_page": 13
}
}
}
Understanding failures
When status is failed, the error field contains a short machine-readable code plus a human message:
{
"status": "failed",
"error": {
"code": "USER_PRIVACY_RESTRICTED",
"message": "The recipient has blocked messages from non-contacts."
}
}
The most common codes are:
USER_PRIVACY_RESTRICTED— contact doesn't accept DMs from strangers. No retry.PEER_FLOOD— your account is being rate-limited by Telegram. We back off automatically.USER_DEACTIVATED— account has been deleted. No retry.NETWORK— transient error. Retried up to 3 times with exponential backoff.
Polling efficiently
For near-real-time sync, keep track of the largest id you've seen and pass it as ?since_id= on the next call, or use the webhooks system to avoid polling entirely.
Edit this page on GitHub
Last updated Jun 17, 2026