GET
/sms/messages
Read message history (sent + received), paginated
Description
Read-only paginated history across both inbound and outbound messages. Does **not** mutate `delivered_at` (use `/sms/receive` for that). Cursor-based keyset pagination — pass the previous response's `next_cursor` as `cursor` to fetch the next page.
Authentication
Bearer required. Send Authorization: Bearer <token>.
Code samples
Pick your runtime. Every sample is in the page source — switching tabs is for your eyes.
curl 'https://agentnumber.really.com/sms/messages?direction=both&since=<since>&until=<until>&limit=50&cursor=<cursor>' \
--header 'Authorization: Bearer <your-token>'interface MessagesResponse {
messages: Record<string, unknown>[];
next_cursor: string | null;
}
const response = await fetch('https://agentnumber.really.com/sms/messages?direction=both&since=<since>&until=<until>&limit=50&cursor=<cursor>', {
headers: {
Authorization: 'Bearer <your-token>'
}
});
if (!response.ok) {
throw new Error(`read message history (sent + received), paginated failed: ${response.status}`);
}
const data = (await response.json()) as MessagesResponse;
requests.get(
"https://agentnumber.really.com/sms/messages",
headers={
"Authorization": "Bearer <your-token>"
},
params={
"direction": "both",
"since": "<since>",
"until": "<until>",
"limit": "50",
"cursor": "<cursor>"
}
)package main
import (
"fmt"
"io"
"net/http"
)
func main() {
requestUrl := "https://agentnumber.really.com/sms/messages?direction=both&since=%3Csince%3E&until=%3Cuntil%3E&limit=50&cursor=%3Ccursor%3E"
req, _ := http.NewRequest("GET", requestUrl, nil)
req.Header.Add("Authorization", "Bearer <your-token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(res)
fmt.Println(string(body))
}fetch('https://agentnumber.really.com/sms/messages?direction=both&since=<since>&until=<until>&limit=50&cursor=<cursor>', {
headers: {
Authorization: 'Bearer <your-token>'
}
})import { request } from 'undici'
const { statusCode, body } = await request('https://agentnumber.really.com/sms/messages?direction=both&since=<since>&until=<until>&limit=50&cursor=<cursor>', {
headers: {
Authorization: 'Bearer <your-token>'
}
})require 'uri'
require 'net/http'
url = URI("https://agentnumber.really.com/sms/messages?direction=both&since=%3Csince%3E&until=%3Cuntil%3E&limit=50&cursor=%3Ccursor%3E")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <your-token>'
response = http.request(request)
puts response.read_bodyimport Foundation
var request = URLRequest(url: URL(string: "https://agentnumber.really.com/sms/messages?direction=both&since=%3Csince%3E&until=%3Cuntil%3E&limit=50&cursor=%3Ccursor%3E")!)
request.httpMethod = "GET"
request.setValue("Bearer <your-token>", forHTTPHeaderField: "Authorization")
let (data, response) = try await URLSession.shared.data(for: request)
guard let httpResponse = response as? HTTPURLResponse,
200..<300 ~= httpResponse.statusCode else {
throw URLError(.badServerResponse)
}
print(String(data: data, encoding: .utf8) ?? "")val client = OkHttpClient()
val request = Request.Builder()
.url("https://agentnumber.really.com/sms/messages")
.get()
.addHeader("Authorization", "Bearer <your-token>")
.build()
val response = client.newCall(request).execute()GET /sms/messages?direction=both&since=<since>&until=<until>&limit=50&cursor=<cursor> HTTP/1.1
Host: agentnumber.really.com
Authorization: Bearer <your-token>
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://agentnumber.really.com/sms/messages"))
.header("Authorization", "Bearer <your-token>")
.method("GET", HttpRequest.BodyPublishers.noBody())
.build();
HttpResponse<String> response = HttpClient.newHttpClient().send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());#import <Foundation/Foundation.h>
NSDictionary *headers = @{ @"Authorization": @"Bearer <your-token>" };
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"https://agentnumber.really.com/sms/messages"]
cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:10.0];
[request setHTTPMethod:@"GET"];
[request setAllHTTPHeaderFields:headers];
NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request
completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
if (error) {
NSLog(@"%@", error);
} else {
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *) response;
NSLog(@"%@", httpResponse);
}
}];
[dataTask resume];using var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Get, "https://agentnumber.really.com/sms/messages?direction=both&since=<since>&until=<until>&limit=50&cursor=<cursor>");
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", "<your-token>");
using var response = await client.SendAsync(request);#include <curl/curl.h>
int main(void) {
curl_global_init(CURL_GLOBAL_DEFAULT);
CURL *curl = curl_easy_init();
if (!curl) {
curl_global_cleanup();
return 1;
}
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "GET");
curl_easy_setopt(curl, CURLOPT_URL, "https://agentnumber.really.com/sms/messages?direction=both&since=<since>&until=<until>&limit=50&cursor=<cursor>");
struct curl_slist *headers = NULL;
headers = curl_slist_append(headers, "Authorization: Bearer <your-token>");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
CURLcode res = curl_easy_perform(curl);
curl_easy_cleanup(curl);
curl_slist_free_all(headers);
curl_global_cleanup();
return (int)res;
}import 'package:http/http.dart' as http;
void main() async {
final headers = <String,String>{
'Authorization': 'Bearer <your-token>',
};
final response = await http.get(Uri.parse('https://agentnumber.really.com/sms/messages?direction=both&since=<since>&until=<until>&limit=50&cursor=<cursor>'), headers: headers);
print(response.body);
}let client = reqwest::Client::new();
let request = client
.get("https://agentnumber.really.com/sms/messages?direction=both&since=<since>&until=<until>&limit=50&cursor=<cursor>")
.header("Authorization", "Bearer <your-token>");
let response = request.send().await?;$ch = curl_init("https://agentnumber.really.com/sms/messages?direction=both&since=<since>&until=<until>&limit=50&cursor=<cursor>");
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Authorization: Bearer <your-token>']);
curl_exec($ch);
curl_close($ch);Query parameters
| Name | Type | Description |
|---|---|---|
direction |
string |
Filter to one direction or the other. Default: both. |
since |
string |
RFC3339 lower bound on `created_at` (inclusive). |
until |
string |
RFC3339 upper bound on `created_at` (inclusive). |
limit |
integer |
Max rows to return. Defaults to 50, capped at 100. |
cursor |
string |
Opaque pagination token from a previous response's `next_cursor`. |
Responses
200 Page of message history. `next_cursor` is `null` on the last page.
{
"messages": [
{
"id": 4821,
"direction": "received",
"from_number": "+15555550199",
"to_number": "+15555550123",
"body": "Your code is 123456",
"message_id": "msg_example_0000000000000000000000",
"status": null,
"created_at": "2026-04-30T18:24:01.000Z",
"delivered_at": "2026-04-30T18:24:01.000Z"
},
{
"id": 4820,
"direction": "sent",
"from_number": "+15555550123",
"to_number": "+15555550199",
"body": "Hello from my agent.",
"message_id": "msg_01HM3PXJ4K8ZFQ5Y7B9W2N6V8Q",
"status": "queued",
"created_at": "2026-04-30T18:23:55.000Z",
"delivered_at": null
}
],
"next_cursor": "4820|4810"
}
401 Missing, invalid, revoked, or expired bearer token.
{
"error": "unauthorized",
"message": "invalid, revoked, or expired token"
}