curl --request GET \
--url https://radiotools.rivi.software/api/v1/stations/{stationSlug}/content \
--header 'Authorization: Bearer <token>'import requests
url = "https://radiotools.rivi.software/api/v1/stations/{stationSlug}/content"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://radiotools.rivi.software/api/v1/stations/{stationSlug}/content', 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://radiotools.rivi.software/api/v1/stations/{stationSlug}/content",
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://radiotools.rivi.software/api/v1/stations/{stationSlug}/content"
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://radiotools.rivi.software/api/v1/stations/{stationSlug}/content")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://radiotools.rivi.software/api/v1/stations/{stationSlug}/content")
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{
"contractVersion": 1,
"type": "news",
"records": [
{
"contractVersion": 1,
"id": "5b961af1-c305-4a1e-aed4-b3dfdc72be09",
"publicationId": "77de95e7-3382-468c-b34a-880491592ae6",
"revision": 3,
"type": "news",
"schemaVersion": 1,
"publishedAt": "2026-10-05T07:45:00.000Z",
"firstPublishedAt": "2026-10-05T07:30:00.000Z",
"values": {
"headline": "Riverside festival opens this weekend",
"featured": true,
"reading_minutes": 2,
"category": "local",
"event_at": "2026-10-10T10:00:00.000Z"
},
"document": {
"version": 1,
"mode": "document",
"blocks": [
{
"id": "8c024c8e-0536-4a80-b3dc-b56580259efe",
"type": "text",
"content": [
{
"text": "The riverside festival opens on Saturday.",
"marks": []
}
]
}
]
},
"media": [
{
"assetId": "645b3141-69f9-439a-8d98-185439063b39",
"versionId": "a6286c77-6253-433b-80e9-38aed5d72a60",
"kind": "image",
"url": "/api/media/public/station-rivier/a6286c77-6253-433b-80e9-38aed5d72a60",
"credits": "Radio Rivier",
"mime": "image/jpeg",
"alt": "Stage on the riverbank before the festival opens",
"width": 2400,
"height": 1600,
"duration": null,
"variants": {
"thumb": "/api/media/public/station-rivier/a6286c77-6253-433b-80e9-38aed5d72a60/thumb",
"display": "/api/media/public/station-rivier/a6286c77-6253-433b-80e9-38aed5d72a60/display",
"card": "/api/media/public/station-rivier/a6286c77-6253-433b-80e9-38aed5d72a60/card",
"square": "/api/media/public/station-rivier/a6286c77-6253-433b-80e9-38aed5d72a60/square"
}
}
],
"related": {
"programIds": [
"581497a3-e8b9-47ad-ade4-e1bf3895450a"
]
}
}
],
"nextCursor": null,
"page": {
"limit": 25,
"nextCursor": null
}
}List content
Read published snapshots for one content type. Send type=news (replace news with a key from schemas), follow nextCursor until null, and filter only allowlisted delivery fields. Drafts and private values are excluded.
curl --request GET \
--url https://radiotools.rivi.software/api/v1/stations/{stationSlug}/content \
--header 'Authorization: Bearer <token>'import requests
url = "https://radiotools.rivi.software/api/v1/stations/{stationSlug}/content"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://radiotools.rivi.software/api/v1/stations/{stationSlug}/content', 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://radiotools.rivi.software/api/v1/stations/{stationSlug}/content",
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://radiotools.rivi.software/api/v1/stations/{stationSlug}/content"
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://radiotools.rivi.software/api/v1/stations/{stationSlug}/content")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://radiotools.rivi.software/api/v1/stations/{stationSlug}/content")
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{
"contractVersion": 1,
"type": "news",
"records": [
{
"contractVersion": 1,
"id": "5b961af1-c305-4a1e-aed4-b3dfdc72be09",
"publicationId": "77de95e7-3382-468c-b34a-880491592ae6",
"revision": 3,
"type": "news",
"schemaVersion": 1,
"publishedAt": "2026-10-05T07:45:00.000Z",
"firstPublishedAt": "2026-10-05T07:30:00.000Z",
"values": {
"headline": "Riverside festival opens this weekend",
"featured": true,
"reading_minutes": 2,
"category": "local",
"event_at": "2026-10-10T10:00:00.000Z"
},
"document": {
"version": 1,
"mode": "document",
"blocks": [
{
"id": "8c024c8e-0536-4a80-b3dc-b56580259efe",
"type": "text",
"content": [
{
"text": "The riverside festival opens on Saturday.",
"marks": []
}
]
}
]
},
"media": [
{
"assetId": "645b3141-69f9-439a-8d98-185439063b39",
"versionId": "a6286c77-6253-433b-80e9-38aed5d72a60",
"kind": "image",
"url": "/api/media/public/station-rivier/a6286c77-6253-433b-80e9-38aed5d72a60",
"credits": "Radio Rivier",
"mime": "image/jpeg",
"alt": "Stage on the riverbank before the festival opens",
"width": 2400,
"height": 1600,
"duration": null,
"variants": {
"thumb": "/api/media/public/station-rivier/a6286c77-6253-433b-80e9-38aed5d72a60/thumb",
"display": "/api/media/public/station-rivier/a6286c77-6253-433b-80e9-38aed5d72a60/display",
"card": "/api/media/public/station-rivier/a6286c77-6253-433b-80e9-38aed5d72a60/card",
"square": "/api/media/public/station-rivier/a6286c77-6253-433b-80e9-38aed5d72a60/square"
}
}
],
"related": {
"programIds": [
"581497a3-e8b9-47ad-ade4-e1bf3895450a"
]
}
}
],
"nextCursor": null,
"page": {
"limit": 25,
"nextCursor": null
}
}Authorizations
Station-scoped listener credential. Send Authorization: Bearer <token>, for example Bearer rtm_…. Sending the rtm_ token alone without Bearer returns 401 UNAUTHENTICATED. In the interactive playground, enter only the raw rtm_ token; the playground adds the prefix. Listener REST and GraphQL: listener:read. Listener devices: push:register.
Path Parameters
Public station slug from the station settings; distinct from the internal station ID.
Query Parameters
Stable published content type key returned by the schemas endpoint.
^[a-z][a-z0-9_]{0,47}$Opaque continuation value from nextCursor. Omit on the first request; pass the returned value unchanged.
1 - 400Maximum number of items per page. See the bounds and default below.
1 <= x <= 50Order records by first publication (publishedAt) or by latest update (updatedAt).
publishedAt, updatedAt Sort direction: desc for newest first, asc for oldest first.
asc, desc Repeatable. field:value (exact), field.contains:value (case-insensitive substring) or field.anyOf:a,b. Text and choice delivery fields only.
10Response
Success; private/no-store
Public JSON contract version. The current version is 1; tolerate additional fields within this version.
1 1
Published content type key; resolve its definition through the schemas endpoint.
^[a-z][a-z0-9_]{0,47}$"news"
Published records matching the content type and filters.
50Show child attributes
Show child attributes
[
{
"contractVersion": 1,
"id": "5b961af1-c305-4a1e-aed4-b3dfdc72be09",
"publicationId": "77de95e7-3382-468c-b34a-880491592ae6",
"revision": 3,
"type": "news",
"schemaVersion": 1,
"publishedAt": "2026-10-05T07:45:00.000Z",
"firstPublishedAt": "2026-10-05T07:30:00.000Z",
"values": {
"headline": "Riverside festival opens this weekend",
"featured": true,
"reading_minutes": 2,
"category": "local",
"event_at": "2026-10-10T10:00:00.000Z"
},
"document": {
"version": 1,
"mode": "document",
"blocks": [
{
"id": "8c024c8e-0536-4a80-b3dc-b56580259efe",
"type": "text",
"content": [
{
"text": "The riverside festival opens on Saturday.",
"marks": []
}
]
}
]
},
"media": [
{
"assetId": "645b3141-69f9-439a-8d98-185439063b39",
"versionId": "a6286c77-6253-433b-80e9-38aed5d72a60",
"kind": "image",
"url": "/api/media/public/station-rivier/a6286c77-6253-433b-80e9-38aed5d72a60",
"credits": "Radio Rivier",
"mime": "image/jpeg",
"alt": "Stage on the riverbank before the festival opens",
"width": 2400,
"height": 1600,
"duration": null,
"variants": {
"thumb": "/api/media/public/station-rivier/a6286c77-6253-433b-80e9-38aed5d72a60/thumb",
"display": "/api/media/public/station-rivier/a6286c77-6253-433b-80e9-38aed5d72a60/display",
"card": "/api/media/public/station-rivier/a6286c77-6253-433b-80e9-38aed5d72a60/card",
"square": "/api/media/public/station-rivier/a6286c77-6253-433b-80e9-38aed5d72a60/square"
}
}
],
"related": {
"programIds": ["581497a3-e8b9-47ad-ade4-e1bf3895450a"]
}
}
]
Continuation cursor for the next page; null means there are no more items. Do not construct or decode it.
400null
Content pagination metadata.
Show child attributes
Show child attributes
{ "limit": 25, "nextCursor": null }
Was this page helpful?