Get message
Returns a message’s status and timestamps. The can be the internal message id, the correlationId, or the provider message id (externalMessageId / Meta wamid). Includes externalMessageId, status, destination, sentAt/deliveredAt/readAt, errorCode and errorMessage when it failed, origin and metaPricing. Requires a number-scoped key.
Requires a number-scoped key.
curl --request GET \
--url https://pilotstatus.com.br/v1/messages/{id} \
--header 'x-api-key: <api-key>'import requests
url = "https://pilotstatus.com.br/v1/messages/{id}"
headers = {"x-api-key": "<api-key>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {'x-api-key': '<api-key>'}};
fetch('https://pilotstatus.com.br/v1/messages/{id}', 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://pilotstatus.com.br/v1/messages/{id}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"x-api-key: <api-key>"
],
]);
$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://pilotstatus.com.br/v1/messages/{id}"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("x-api-key", "<api-key>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://pilotstatus.com.br/v1/messages/{id}")
.header("x-api-key", "<api-key>")
.asString();require 'uri'
require 'net/http'
url = URI("https://pilotstatus.com.br/v1/messages/{id}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["x-api-key"] = '<api-key>'
response = http.request(request)
puts response.read_body{
"id": "msg_01HZX...",
"externalMessageId": "wamid.HBg...",
"status": "DELIVERED",
"correlationId": "corr_01HZX...",
"destinationNumber": "5511988887777",
"createdAt": "2026-06-20T10:00:00.000Z",
"sentAt": "2026-06-20T10:00:01.000Z",
"deliveredAt": "2026-06-20T10:00:03.000Z",
"readAt": null,
"errorCode": null,
"errorMessage": null,
"template": "boas_vindas",
"origin": "API",
"metaPricing": null
}{
"error": "Validation error"
}{
"error": "Unauthorized"
}{
"error": "Tenant-scoped keys cannot call number endpoints",
"code": "TENANT_SCOPE_NOT_ALLOWED"
}{
"error": "Too many requests"
}Authorizations
Your ps_ API key
Path Parameters
Internal id, correlationId, or externalMessageId (Meta wamid).
Response
Get message
Internal message id — the id returned by POST /v1/messages/send.
"msg_01HZX..."
Provider message id (on an official number, Meta's wamid). null until the provider accepts the message.
"wamid.HBg..."
Current delivery status.
QUEUED, SENT, DELIVERED, READ, PLAYED, FAILED, CANCELED "FAILED"
Correlation identifier of the send.
"corr_01HZX..."
Destination phone number.
"5511988887777"
When the message was created (UTC, ISO 8601).
"2026-06-20T10:00:00.000Z"
When the message was sent, or null.
"2026-06-20T10:00:01.000Z"
When the message was delivered, or null.
null
When the message was read, or null.
null
Machine-readable failure reason — the same value GET /v1/messages returns for this message. null when there is no error, and always null on DELIVERED, READ, PLAYED and CANCELED. Branch on this, never on errorMessage. The set grows (see Log Error Codes): treat an unknown code as "needs review".
"META_OUTSIDE_24H_WINDOW"
Human-readable failure reason, or null. Its wording is not a contract — do not parse it; use errorCode.
"Re-engagement message: Message failed to send because more than 24 hours have passed since the customer last replied to this number."
Name of the template the message was sent with. The key is omitted (not null) when the send used no template.
"boas_vindas"
Which rail the message went out on. null means no recognised send request — it does not mean inbound. Outbound messages Pilot Status did not send — APP, LAYER, and CHATWOOT replies from a native WhatsApp Cloud inbox — are listed only by GET /v1/messages and GET /v1/messages/history; this endpoint answers 404 for them.
API, MCP, CHATWOOT, CHAT, DASHBOARD, SYSTEM, null "API"
Meta's own billing verdict for this message. null until Meta reports it, and always null on non-Meta numbers.
Show child attributes
Show child attributes
Was this page helpful?
curl --request GET \
--url https://pilotstatus.com.br/v1/messages/{id} \
--header 'x-api-key: <api-key>'import requests
url = "https://pilotstatus.com.br/v1/messages/{id}"
headers = {"x-api-key": "<api-key>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {'x-api-key': '<api-key>'}};
fetch('https://pilotstatus.com.br/v1/messages/{id}', 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://pilotstatus.com.br/v1/messages/{id}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"x-api-key: <api-key>"
],
]);
$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://pilotstatus.com.br/v1/messages/{id}"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("x-api-key", "<api-key>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://pilotstatus.com.br/v1/messages/{id}")
.header("x-api-key", "<api-key>")
.asString();require 'uri'
require 'net/http'
url = URI("https://pilotstatus.com.br/v1/messages/{id}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["x-api-key"] = '<api-key>'
response = http.request(request)
puts response.read_body{
"id": "msg_01HZX...",
"externalMessageId": "wamid.HBg...",
"status": "DELIVERED",
"correlationId": "corr_01HZX...",
"destinationNumber": "5511988887777",
"createdAt": "2026-06-20T10:00:00.000Z",
"sentAt": "2026-06-20T10:00:01.000Z",
"deliveredAt": "2026-06-20T10:00:03.000Z",
"readAt": null,
"errorCode": null,
"errorMessage": null,
"template": "boas_vindas",
"origin": "API",
"metaPricing": null
}{
"error": "Validation error"
}{
"error": "Unauthorized"
}{
"error": "Tenant-scoped keys cannot call number endpoints",
"code": "TENANT_SCOPE_NOT_ALLOWED"
}{
"error": "Too many requests"
}