curl --request GET \
--url https://notifications.{region}.basaltic.sh/v1/topics/{topic_id}/messages \
--header 'Authorization: Bearer <token>'import requests
url = "https://notifications.{region}.basaltic.sh/v1/topics/{topic_id}/messages"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://notifications.{region}.basaltic.sh/v1/topics/{topic_id}/messages', 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://notifications.{region}.basaltic.sh/v1/topics/{topic_id}/messages",
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://notifications.{region}.basaltic.sh/v1/topics/{topic_id}/messages"
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://notifications.{region}.basaltic.sh/v1/topics/{topic_id}/messages")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://notifications.{region}.basaltic.sh/v1/topics/{topic_id}/messages")
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{
"messages": [
{
"crn": "crn:notifications:sa-saopaulo-1:acme:message/019400aa-bbbb-7ccc-8ddd-eeeeffff0000",
"id": "019400aa-bbbb-7ccc-8ddd-eeeeffff0000",
"fanout_state": "complete",
"delivery_count": 3,
"published_at": "2026-01-18T11:45:00Z",
"subject": "Disk pressure on europa",
"message_structure": "",
"attributes": {
"severity": {
"type": "String",
"value": "critical"
},
"latency": {
"type": "Number",
"value": "250"
}
},
"fanned_out_at": "2026-01-18T11:45:01Z"
}
],
"meta": {
"total": 150,
"limit": 20,
"marker": "550e8400-e29b-41d4-a716-446655440000",
"has_more": true
}
}{
"error": {
"code": "INVALID_INPUT",
"message": "Invalid request parameters",
"request_id": "550e8400-e29b-41d4-a716-446655440000"
}
}{
"error": {
"code": "UNAUTHORIZED",
"message": "Authentication required",
"request_id": "550e8400-e29b-41d4-a716-446655440000"
}
}{
"error": {
"code": "ACCESS_DENIED",
"message": "You don't have permission to perform this action",
"request_id": "550e8400-e29b-41d4-a716-446655440000"
}
}{
"error": {
"code": "NOT_FOUND",
"message": "Resource not found",
"request_id": "550e8400-e29b-41d4-a716-446655440000"
}
}List messages
Lists published message metadata for this topic, newest IDs first. Use the marker to continue through older messages. Message bodies are not included. The optional filters intersect with this topic.
curl --request GET \
--url https://notifications.{region}.basaltic.sh/v1/topics/{topic_id}/messages \
--header 'Authorization: Bearer <token>'import requests
url = "https://notifications.{region}.basaltic.sh/v1/topics/{topic_id}/messages"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://notifications.{region}.basaltic.sh/v1/topics/{topic_id}/messages', 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://notifications.{region}.basaltic.sh/v1/topics/{topic_id}/messages",
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://notifications.{region}.basaltic.sh/v1/topics/{topic_id}/messages"
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://notifications.{region}.basaltic.sh/v1/topics/{topic_id}/messages")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://notifications.{region}.basaltic.sh/v1/topics/{topic_id}/messages")
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{
"messages": [
{
"crn": "crn:notifications:sa-saopaulo-1:acme:message/019400aa-bbbb-7ccc-8ddd-eeeeffff0000",
"id": "019400aa-bbbb-7ccc-8ddd-eeeeffff0000",
"fanout_state": "complete",
"delivery_count": 3,
"published_at": "2026-01-18T11:45:00Z",
"subject": "Disk pressure on europa",
"message_structure": "",
"attributes": {
"severity": {
"type": "String",
"value": "critical"
},
"latency": {
"type": "Number",
"value": "250"
}
},
"fanned_out_at": "2026-01-18T11:45:01Z"
}
],
"meta": {
"total": 150,
"limit": 20,
"marker": "550e8400-e29b-41d4-a716-446655440000",
"has_more": true
}
}{
"error": {
"code": "INVALID_INPUT",
"message": "Invalid request parameters",
"request_id": "550e8400-e29b-41d4-a716-446655440000"
}
}{
"error": {
"code": "UNAUTHORIZED",
"message": "Authentication required",
"request_id": "550e8400-e29b-41d4-a716-446655440000"
}
}{
"error": {
"code": "ACCESS_DENIED",
"message": "You don't have permission to perform this action",
"request_id": "550e8400-e29b-41d4-a716-446655440000"
}
}{
"error": {
"code": "NOT_FOUND",
"message": "Resource not found",
"request_id": "550e8400-e29b-41d4-a716-446655440000"
}
}notifications:ListMessages on the topic. See Notifications permissions.Authorizations
An OAuth 2.0 bearer token, sent as Authorization: Bearer <token>.
This is the recommended way to authenticate.
Get one by exchanging a service account's access key pair at
POST /v1/oauth/token with grant_type=client_credentials. It is the
standard client-credentials grant, so any OAuth-aware library will
obtain and refresh it for you.
curl -s -u "$KEY_ID:$SECRET" -d grant_type=client_credentials \
https://iam.basaltic.sh/v1/oauth/token
Tokens last an hour by default. The same access key pair is separately your AWS SigV4 credential for the S3-compatible object endpoint, which speaks nothing else.
Path Parameters
"a1b2c3d4-5e6f-4a7b-8c9d-0e1f2a3b4c5d"
Query Parameters
Exact message CRN. Foreign identities return an empty page; malformed CRNs are invalid.
"crn:notifications:sa-saopaulo-1:acme:message/019400aa-bbbb-7ccc-8ddd-eeeeffff0000"
pending, complete "complete"
Id of the last item on the previous page.
"a1b2c3d4-5e6f-4a7b-8c9d-0e1f2a3b4c5d"
Maximum items to return. A larger value is clamped to the maximum rather than rejected, so page until meta.has_more is false.
1 <= x <= 20050

