Metadata
Push "now playing" information to sonicast and read the current state of a program.
sonicast keeps a now playing state for every program. A playout system (or any script) pushes what is currently on air, and sonicast turns it into the in-stream text shown to listeners in their players.
Prerequisites
API keys are created in the dashboard. The
examples below read the key from the $SONICAST_API_KEY environment variable.
export SONICAST_API_KEY=sk_***Every request is authenticated with the key as a Bearer token. The whoami
endpoint returns the account the key belongs to, which makes it a quick way to
check a key:
curl \ -H "Accept: application/json" \ -H "Authorization: Bearer $SONICAST_API_KEY" \ https://sonicast.io/api/v1/whoami/Programs are addressed as BRAND_KEY:PROGRAM_KEY, for example
/api/v1/programs/acme:default/. The program uid (for example
/api/v1/programs/W3D4J4PV/) works as well. Unlike the keys, the uid never
changes, so use it where a URL must keep working after a key is renamed.
Now playing
Get now playing
Returns the current state of the program. Expired layers are returned as
null, and stream_text is the text currently used in the stream.
curl \ -H "Accept: application/json" \ -H "Authorization: Bearer $SONICAST_API_KEY" \ https://sonicast.io/api/v1/programs/BRAND_KEY:PROGRAM_KEY/now-playing/{
"item": {
"type": "music",
"title": "Enjoy the Silence",
"artist": "Depeche Mode",
"duration": 60,
"started_at": "2026-09-28T08:00:00Z",
"image_url": null
},
"show": null,
"stream_text": "Depeche Mode - Enjoy the Silence"
}Update the current item
An item is sent whenever a new element starts playing. With a duration (in
seconds), the item expires on its own if the playout stops sending updates.
started_at defaults to the time of the request.
curl \ -X POST \ -H "Content-Type: application/json" \ -H "Accept: application/json" \ -H "Authorization: Bearer $SONICAST_API_KEY" \ -d '{ "item": { "type": "music", "title": "Enjoy the Silence", "artist": "Depeche Mode", "duration": 60 } }' \ https://sonicast.io/api/v1/programs/BRAND_KEY:PROGRAM_KEY/now-playing/Only layers present in the payload are changed. Sending an item leaves the
current show as it is, and the other way round.
Clear the current item
Sending null removes a layer right away, e.g. when the playout stops. The
stream text then falls back to the show or the program name.
curl \ -X POST \ -H "Content-Type: application/json" \ -H "Accept: application/json" \ -H "Authorization: Bearer $SONICAST_API_KEY" \ -d '{"item": null}' \ https://sonicast.io/api/v1/programs/BRAND_KEY:PROGRAM_KEY/now-playing/Update the show
Sets the show that is on air. Its title is used as stream text whenever no
music item is playing (e.g. during talk, news or jingles). With ends_at, the
show expires at the end of its slot.
curl \ -X POST \ -H "Content-Type: application/json" \ -H "Accept: application/json" \ -H "Authorization: Bearer $SONICAST_API_KEY" \ -d '{ "show": { "title": "Morning Show", "description": "Morning programme" } }' \ https://sonicast.io/api/v1/programs/BRAND_KEY:PROGRAM_KEY/now-playing/Playout integrations
Playout systems that can only call a URL template, or send their own format, are covered in Playout integrations.
from django.db.models import QuerySetfrom django.http import Http404from django.shortcuts import get_object_or_404from tenancy.models import BrandMember, Programfrom tenancy.selectors import BRAND_MANAGER_ROLESfrom api_pub.models import ApiKeydef api_key_list(*, brand): return ( ApiKey.objects.filter(brand=brand) .select_related("created_by") .prefetch_related("restricted_programs") )def api_key_get_for_manager(*, user, uid: str) -> ApiKey: return get_object_or_404( ApiKey.objects.select_related("brand", "created_by").prefetch_related( "restricted_programs" ), uid=uid, brand__memberships__user=user, brand__memberships__role__in=BRAND_MANAGER_ROLES, )def brand_is_manager(*, brand, user) -> bool: return BrandMember.objects.filter( brand=brand, user=user, role__in=BRAND_MANAGER_ROLES, ).exists()