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.
Callbacks are the requests our servers will send to your server when a song is recognized on one of your streams and when something happens to a stream. The callbacks will be sent to the specified URL as a JSON structure in the POST payload. The format is below. You’ll receive callbacks with results and with notifications. Alternatively, you can use longpoll (see below); the bodies are the same.
Note: These examples are captured API responses.
Result callback body
By default, we will send new results after songs end playing, with the total streamed time in play_length. If you add the stream with callbacks=before, we will send the results when songs start playing, and play_length isn’t 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 result of the recognition for one stream event |
result object
| Field | Type | Description |
|---|---|---|
radio_id | integer | The integer you chose when you added the stream. It identifies the stream this result came from |
timestamp | string | The time of the recognition, YYYY-MM-DD HH:MM:SS |
play_length | integer | The total streamed time of the song, in seconds. Not meaningful with callbacks="before" |
results | array | The recognized songs (see below) |
results array entries
The results contain the recognized songs. There can be several songs in one callback, so read all the objects in the array, not just the first one.
| Field | Type | Description |
|---|---|---|
artist | string | null | The artist (or artists) of the track. May be null for a custom-catalog match |
title | string | null | The title of the track. May be null for a custom-catalog match |
album | string | The album the recording appears on |
release_date | string | The release date, YYYY-MM-DD |
label | string | The publishing label |
score | integer | The confidence of the match, 0–100; the higher, the stronger |
song_link | string | The universal link to the song’s page on lis.tn |
Notification callback body
Notifications are information about the state of the streams. If something happens to an audio stream, we’ll let you know by sending a notification so you can fix the stream or change its URL. We also send a notification with the code 0 when a stream is fine. Notifications also contain the time of sending, and they don’t contain songs.
{
"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 details (see below) |
time | integer | The time of sending, in Unix epoch seconds |
notification object
| Field | Type | Description |
|---|---|---|
radio_id | integer | The integer that identifies the stream this notification is about |
stream_running | boolean | Whether the music is being recognized from the stream right now. false when AudD has stopped because of the condition in notification_code |
notification_code | integer | The code of the condition (see the table below) |
notification_message | string | The description of the condition, in human-readable form |
notification_code values
| Code | Meaning |
|---|---|
0 | Everything’s fine |
650 | AudD can’t connect to the stream |
651 | AudD doesn’t receive any music from the stream, only white noise |
Exactly one of result or notification per callback
There are 2 kinds of callbacks: results (which means that the status is "success" and the songs are in result.results) and notifications (which means that the status is "-" and the code is in notification.notification_code). A callback contains either result or notification, never both.
status | Key | Read |
|---|---|---|
"success" | result | result.results |
"-" | notification | notification.notification_code |
If the status is neither "success" nor "-", it’s an error on our side, not a stream event.
Longpoll response
In addition to callbacks, you can use HTTP longpolling to get new results from any number of clients without having to spin up a web server or have a static IP. The longpoll address is https://api.audd.io/longpoll/; send GET requests to it. We send the response when an event is ready or when the timeout has elapsed.
Please use longpolling after setting a working callback URL using the setCallbackUrl method; set https://audd.tech/empty/ as the callback URL if you don’t have any URL that can receive POST requests. If no callback URL is set, longpoll might never return any events, even while songs are being recognized.
As the subscription category, use the longpoll_category field from the getStreams response. You can share the categories with your clients or users, but please don’t include your API tokens in the client-side software.
Request parameters:
| Parameter | Type | Description |
|---|---|---|
category | string | The subscription category: the longpoll_category of the stream |
timeout | integer | How many seconds to wait for an event |
since_time | integer | The timestamp from the previous response |
If you’re making the longpoll requests manually, here’s an example of a longpoll URL:
https://api.audd.io/longpoll/?category=92b1cc7f0&timeout=50&since_time=1652123144400
When an event is available, the response has the same shape as the result callback body. When you receive a response containing the timestamp field, use it as the updated since_time for the new request.
No-events keepalive
If there are no events before the timeout, we respond with the timeout field and a timestamp:
{
"timeout": "no events before timeout",
"timestamp": 1777901270049
}
This is normal. Just send the request again, with the timestamp as the new since_time.
| Field | Type | Description |
|---|---|---|
timeout | string | The keepalive marker, "no events before timeout" |
timestamp | integer | The cursor to pass as since_time on your next longpoll request |
getStreams list
Use the getStreams method (POST https://api.audd.io/getStreams/) to get all the streams registered on the account. If there are no streams, the result field is an empty array:
{
"status": "success",
"result": []
}
The fields of a stream:
| Field | Type | Description |
|---|---|---|
radio_id | integer | The integer you assigned when you added the stream |
url | string | The URL of the audio stream (or a shortcut like youtube:5qap5aO4i9A or twitch:monstercat) |
stream_running | boolean | Whether the music is being recognized from the stream now |
longpoll_category | string | The subscription category for longpoll. You can share it with your clients without exposing your API token |
SDK note
We’ve implemented callback parsing and longpoll clients in the SDKs (e.g., in the Go library). parseCallback (or handleCallback, depending on the SDK) returns a result object or a notification object, so you don’t check status by hand, and the longpoll client returns the same objects and keeps the since_time for you.
Notes
If your server doesn’t respond to the callbacks with the 200 OK status or we can’t connect to your server, we’ll put the callbacks in a queue. When your server is back online, we’ll gradually send all the backlog. We have a rate limit for the requests we’re sending: if you have fewer than 500 streams, you won’t receive more than 3 callbacks per second (with a burst size of 15).
If you want additional metadata (e.g. Apple Music, Spotify, MusicBrainz metadata) to be returned with the callbacks, contact us: [email protected]. By default, the callbacks don’t include ISRCs, UPCs, or provider metadata.
score is the confidence of the match, 0–100; the higher, the stronger.
For the songs from your custom catalog, the result contains the audio_id you set when you uploaded the song, and artist and title can be null.
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.
