Stream callback and longpoll payload reference
The exact JSON your callback receiver and longpoll consumer get from AudD streams: result bodies, notification bodies, the getStreams list, and the longpoll keepalive.
This page documents what arrives at your callback receiver (or longpoll consumer) when AudD recognizes music on a registered stream. The payloads below are captured API responses. There are two callback shapes — a result and a notification — and exactly one of them is present per callback. Longpoll delivers the same result bodies, plus a keepalive shape when nothing has happened.
Result callback body
When AudD recognizes a song on one of your streams, it POSTs a JSON body to
your configured callback URL. By default this is sent after the song
finishes playing (and carries the total played time in play_length); with
callbacks="before" it is sent at song start and play_length is not
meaningful.
{
"status": "success",
"result": {
"radio_id": 7,
"timestamp": "2020-04-13 10:31:43",
"play_length": 111,
"results": [
{
"artist": "Alan Walker, A$AP Rocky",
"title": "Live Fast (PUBGM)",
"album": "Live Fast (PUBGM)",
"release_date": "2019-07-25",
"label": "MER Recordings",
"score": 100,
"song_link": "https://lis.tn/LiveFastPUBGM"
}
]
}
}
Top-level fields
| Field | Type | Description |
|---|---|---|
status | string | "success" on a result callback. |
result | object | The recognition result for one stream event. |
result object
| Field | Type | Description |
|---|---|---|
radio_id | integer | The integer you chose when you added the stream. Identifies which stream this result came from. |
timestamp | string | When the recognition occurred, formatted YYYY-MM-DD HH:MM:SS. |
play_length | integer | Total time, in seconds, the song was streamed. Present on default (song-end) callbacks; not meaningful with callbacks="before". |
results | array | The recognized song(s). See below. A result body can contain more than one candidate song. |
results array entries
Each entry describes one recognized track. A single callback’s results
array can hold multiple candidate songs, so iterate it rather than reading
only the first element.
| Field | Type | Description |
|---|---|---|
artist | string | null | Track artist(s). May be null for a custom-catalog match. |
title | string | null | Track title. May be null for a custom-catalog match. |
album | string | Album the recording appears on. |
release_date | string | Release date, YYYY-MM-DD. |
label | string | Publishing label. |
score | integer | Match confidence, 0–100. Higher is a stronger match. |
song_link | string | Universal link to the song’s page on lis.tn. |
Notification callback body
When something goes wrong with a stream — or to confirm a stream is healthy — AudD POSTs a notification instead of a result. A notification tells you to fix or re-point a stream; it never contains a recognized song.
{
"status": "-",
"notification": {
"radio_id": 3,
"stream_running": false,
"notification_code": 650,
"notification_message": "Recognition failed: can't connect to the audiostream"
},
"time": 1587939136
}
Top-level fields
| Field | Type | Description |
|---|---|---|
status | string | "-" on a notification callback (not "success"). |
notification | object | The notification detail. See below. |
time | integer | Unix epoch seconds at which the notification was sent. |
notification object
| Field | Type | Description |
|---|---|---|
radio_id | integer | The stream this notification is about. |
stream_running | boolean | Whether the stream is currently being recognized. false when AudD has stopped because of the condition in notification_code. |
notification_code | integer | The condition code. See the table below. |
notification_message | string | Human-readable description of the condition. |
notification_code values
| Code | Meaning |
|---|---|
0 | Everything is fine. |
650 | Can’t connect to the stream. |
651 | No music from the stream — white noise only. |
Exactly one of result or notification per callback
Each callback POST carries either a result object or a notification
object, never both. Branch on which key is present (or on status):
statusis"success"and aresultkey is present → a recognition result. Readresult.results.statusis"-"and anotificationkey is present → a stream notification. Readnotification.notification_code.
Treat any unexpected status value as a server-side error rather than a
stream event.
Longpoll response
Longpoll is an alternative to running a callback server: GET https://api.audd.io/longpoll/ holds the request open until an event is
ready or the timeout elapses. A working callback URL must still be
configured for the account — longpoll may never return events for an account
with no callback URL set, even while songs are being recognized.
Request parameters:
| Parameter | Type | Description |
|---|---|---|
category | string | The subscription key. Use the longpoll_category value from a getStreams row. |
timeout | integer | Seconds to hold the request open waiting for an event. |
since_time | integer | The timestamp from your previous longpoll response, used as the cursor for the next request. |
Example request URL:
https://api.audd.io/longpoll/?category=92b1cc7f0&timeout=50&since_time=1652123144400
When an event is available, the response carries the same result body shape
documented in Result callback body. When you
receive a response containing a timestamp field, use that value as the
since_time on your next request.
No-events keepalive
When the timeout elapses with nothing to report, longpoll returns a keepalive rather than an event. This is normal; reissue the request.
{
"timeout": "no events before timeout",
"timestamp": 1777901270049
}
| Field | Type | Description |
|---|---|---|
timeout | string | "no events before timeout" — the keepalive marker. |
timestamp | integer | The cursor to pass as since_time on your next longpoll request. |
getStreams list
POST https://api.audd.io/getStreams/ returns every stream registered on
the account. The result is an array of stream rows. When no streams are
registered, the array is empty:
{
"status": "success",
"result": []
}
A populated row describes one registered stream:
| Field | Type | Description |
|---|---|---|
radio_id | integer | The integer you assigned when adding the stream. |
url | string | The stream URL — a direct stream URL or a shortcut such as youtube:5qap5aO4i9A or twitch:monstercat. |
stream_running | boolean | Whether the stream is currently being recognized. |
longpoll_category | string | The subscription key to pass as the longpoll category. Safe to share with clients without exposing your API token. |
SDK note
The SDKs parse a raw callback body into a typed value that is either a match
result or a notification, so your handler branches on a type rather than
inspecting status by hand. Look for the callback-parsing method on the
streams surface — for example parseCallback / handleCallback — which
accepts the raw POST body and returns the typed result-or-notification. The
longpoll consumers (such as the Go library’s longpoll client) hand you the
same typed result objects and manage the since_time cursor for you.
Notes
- The
scorefield on a result entry is a 0–100 confidence value; higher is a stronger match. - A custom-catalog match returns the track ID you uploaded;
artistandtitlemay be null on those entries. - ISRCs, UPCs, and provider metadata (Apple Music, Spotify, MusicBrainz) are not in the default stream callback. Contact [email protected] to enable additional metadata on your callbacks.
- If your server doesn’t return
200 OK, AudD queues the callbacks and re-sends the backlog gradually once your server is reachable again.
Related
Reading this as an AI agent? The raw Markdown is at reference/streams-callback-shape.md, and the full index is /resources/llms.txt.
