List message delivery logs
List the messages your organization sent or received and what happened to each one — delivered, failed, or blocked — with the recipient and the failure reason. The same rows as Settings → Logs, so you can review delivery in bulk instead of opening conversations one at a time.
Statuses are a lifecycle, not a set of outcomes. SENT, DELIVERED and READ all mean the message went out; they differ only in how far it got. SENT means it left Boom and no receipt has come back yet. To count what you sent, ask for all three — asking for SENT alone returns only the ones still unconfirmed.
How far a message can get depends on the channel. WhatsApp reaches READ. Email never does: there is no read receipt, so an email resting at DELIVERED is fully settled. PENDING on an inbound message is normal and permanent — nobody sends a receipt for a message a customer wrote to you.
This is a log of messages, not a delivery-rate report. A few send failures never create a row at all, so an absent message is not proof that nothing was attempted.
curl --request GET \
--url https://www.useboom.ai/api/v1/message-logs \
--header 'Authorization: Bearer <token>'import requests
url = "https://www.useboom.ai/api/v1/message-logs"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://www.useboom.ai/api/v1/message-logs', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://www.useboom.ai/api/v1/message-logs",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://www.useboom.ai/api/v1/message-logs"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://www.useboom.ai/api/v1/message-logs")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://www.useboom.ai/api/v1/message-logs")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"range": {
"from": "<string>",
"to": "<string>"
},
"data": [
{
"id": "<string>",
"direction": "INBOUND",
"channel": "WHATSAPP",
"status": "PENDING",
"createdAt": "<string>",
"sentAt": "<string>",
"deliveredAt": "<string>",
"readAt": "<string>",
"failedAt": "<string>",
"errorMessage": "<string>",
"errorCode": "<string>",
"imported": true,
"recipient": {
"name": "<string>",
"phone": "<string>",
"email": "<string>"
}
}
],
"next_cursor": "<string>"
}{
"error": {
"code": "<string>",
"message": "<string>"
}
}{
"error": {
"code": "<string>",
"message": "<string>"
}
}{
"error": {
"code": "<string>",
"message": "<string>"
}
}{
"error": {
"code": "<string>",
"message": "<string>"
}
}{
"error": {
"code": "<string>",
"message": "<string>"
}
}{
"error": {
"code": "<string>",
"message": "<string>"
}
}{
"error": {
"code": "<string>",
"message": "<string>"
}
}{
"error": {
"code": "<string>",
"message": "<string>"
}
}Authorizations
Organization API key, sent as Authorization: Bearer boom_org_....
Query Parameters
Keep only these statuses. Omit for every status. Several as a list, or over HTTP as one comma-separated value: ?status=SENT,DELIVERED,READ.
PENDING, SENT, DELIVERED, READ, FAILED Keep only these channels. Omit for every channel. Several as a list, or over HTTP as one comma-separated value: ?channel=WHATSAPP,SMS.
WHATSAPP, EMAIL, SMS, VOICE, WEB_CHAT, WEB_WIDGET, FACEBOOK_MESSENGER, INSTAGRAM Defaults to OUTBOUND — a delivery status only means something for a message you sent. Pass INBOUND for what customers sent you.
INBOUND, OUTBOUND Only messages created at or after this moment. A date (2026-08-01) or a full ISO 8601 timestamp.
Only messages created at or before this moment. A date (2026-08-01) or a full ISO 8601 timestamp.
Match the recipient's name, phone or email address. A phone matches in any format.
100Page size, up to 1000.
1 <= x <= 1000Opaque cursor from a previous page.
Was this page helpful?
curl --request GET \
--url https://www.useboom.ai/api/v1/message-logs \
--header 'Authorization: Bearer <token>'import requests
url = "https://www.useboom.ai/api/v1/message-logs"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://www.useboom.ai/api/v1/message-logs', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://www.useboom.ai/api/v1/message-logs",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://www.useboom.ai/api/v1/message-logs"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://www.useboom.ai/api/v1/message-logs")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://www.useboom.ai/api/v1/message-logs")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"range": {
"from": "<string>",
"to": "<string>"
},
"data": [
{
"id": "<string>",
"direction": "INBOUND",
"channel": "WHATSAPP",
"status": "PENDING",
"createdAt": "<string>",
"sentAt": "<string>",
"deliveredAt": "<string>",
"readAt": "<string>",
"failedAt": "<string>",
"errorMessage": "<string>",
"errorCode": "<string>",
"imported": true,
"recipient": {
"name": "<string>",
"phone": "<string>",
"email": "<string>"
}
}
],
"next_cursor": "<string>"
}{
"error": {
"code": "<string>",
"message": "<string>"
}
}{
"error": {
"code": "<string>",
"message": "<string>"
}
}{
"error": {
"code": "<string>",
"message": "<string>"
}
}{
"error": {
"code": "<string>",
"message": "<string>"
}
}{
"error": {
"code": "<string>",
"message": "<string>"
}
}{
"error": {
"code": "<string>",
"message": "<string>"
}
}{
"error": {
"code": "<string>",
"message": "<string>"
}
}{
"error": {
"code": "<string>",
"message": "<string>"
}
}