Use the AudD streams API on api.audd.io to identify the songs playing on radio stations (or any other live audio). Callbacks are the requests with recognition results AudD’s servers will send to your server. Read these caveats before you write a streams integration.
1. The callback URL is set once for the whole account
Set the URL for callbacks using the setCallbackUrl API method. The callbacks from all the streams will be sent to the specified URL as a JSON structure in the POST payload. There is no per-stream callback URL.
Don’t call setCallbackUrl on every addStream. Set it once, at setup. Calling it again overrides the callback URL for all existing streams, not only the new one, and does not trigger a warning. Route per-stream by the radio_id in the callback body instead: it uniquely identifies a given stream.
Don’t call setCallbackUrl on every addStream. Set it once, at setup. Calling it again overrides the callback URL for all existing streams, not only the new one, and does not trigger a warning. Route per-stream by the radio_id in the callback body instead: it uniquely identifies a given stream.
2. addStream accepts direct URLs and three shortcuts
Send the stream URL in the url parameter of addStream. It supports most of the stream formats and the Twitch and YouTube shortcuts:
- Direct stream URLs: HLS, Icecast, .m3u / .m3u8, plain MP3 streams, etc.
- twitch:<channel>, like twitch:monstercat for twitch.tv/monstercat.
- youtube:<video_id>, like youtube:5qap5aO4i9A (a specific live video).
- youtube-ch:<channel_id>, like youtube-ch:UC3zwjSYv4k5HKGXCHMpjVRg, the channel’s current live stream.
Use the shortcut form for Twitch and YouTube rather than pasting a watch URL: the shortcut is what the API resolves.
3. Longpoll needs a callback URL too
With GET https://api.audd.io/longpoll/, you can get the new results without having to run a public web server. Longpoll only works after you set a callback URL using the setCallbackUrl method. If you don’t set the callback URL, longpoll will return no results, and it won’t return an error that explains why. Agents often think longpoll is broken because of this.
Set the callback URL even if you want to use longpoll only. Point it at https://audd.tech/empty/: it’s a no-op receiver that always responds with 200 OK. Longpoll will then deliver the results back to your loop.
Set the callback URL even if you want to use longpoll only. Point it at https://audd.tech/empty/: it’s a no-op receiver that always responds with 200 OK. Longpoll will then deliver the results back to your loop.
You can use longpoll instead of or together with receiving callbacks. Longpoll is part of streams, not a standalone feature. If a song is missing from your longpoll loop, check the callback URL first.
4. A callback body carries a result OR a notification, never both
You’ll receive callbacks with results and with notifications. Each callback body contains either a result or a notification, but not both.
The results contain the recognized songs:
Notifications are information about the health of the streams, and they don’t contain songs:
If something happens to an audio stream, AudD sends a notification so you can fix the stream or change its URL. There are 3 codes you must handle:
Don’t assume every callback has a result. Every 650 or 651 notification will cause an exception in code that reads body["result"] unconditionally. If the notification field exists, the callback is a notification and has no result, so check for it first. Handle the 650 (fix or re-set the stream URL) and 651 (the source isn’t playing music) codes gracefully, so that they are reported rather than crashing your code.
Don’t assume every callback has a result. Every 650 or 651 notification will cause an exception in code that reads body["result"] unconditionally. If the notification field exists, the callback is a notification and has no result, so check for it first. Handle the 650 (fix or re-set the stream URL) and 651 (the source isn’t playing music) codes gracefully, so that they are reported rather than crashing your code.
5. callbacks="before" sends callbacks when songs start
By default, result callbacks are sent after the song ends and contain the total streamed time of the song. Pass callbacks=before to addStream if you want to receive the callbacks as soon as a song starts playing (instead of when it ends).
With callbacks=before, you won’t receive the total played time in the callbacks, since the song hasn’t finished yet and there’s nothing to total. With before, the match arrives earlier. Pick before for now-playing displays. For logging how long songs played, keep the end-of-song callbacks. This is the default and doesn’t need to be set.
6. The test token doesn’t work with streams
Please note that api_token=test works only on the standard endpoint, with a limit of 10 requests per day. The setCallbackUrl, addStream, and longpoll methods will not accept the test token, so there’s no hello-world shortcut for streams. To use streams, get your own token at dashboard.audd.io and send it from the first call.
- Callbacks vs. longpoll
- Standard vs. enterprise vs. streams
- Recipe: now-playing widget
- Streams (API reference)







