# Music recognition for audio streams API Docs



You can use the AudD real-time music recognition service for audio streams to identify the songs that are being played on radio stations (or any other streams)

:::info

The music recognition costs $45 per audio stream per month with our music DB. Or $25 per stream per month if you have your own content that you want to recognize instead of using our music DB. In the second case, contact us: [api@audd.io](mailto:api@audd.io).

:::

We wanted to make the API as simple as possible: you send us the URLs of radio streams, and we send you the recognition results in real time.

If you don't have a server to receive the results and just want to download reports as, e.g., sheets, or a bot that posts the currently playing song to  YouTube, Twitch or Discord chats, contact us. You'll be able to use our service without interacting with the API. You can also use our [Twitch extension](https://audd.cc/twitch).

## How to use it:

<div class="markdown request-section">

### 1. Set the limit of audio streams

Set the maximum limit of concurrent audio streams and make a payment [on the API Dashboard](https://dashboard.audd.io/). (If you want to test the service for free, reach out: api@audd.io.)

After this, you can interact with the API using <a href="https://audd.io/streams/">a web interface</a>, which allows adding, removing, and updating streams, as well as downloading the last 40 music recognition results. (If you don't set up a server for callbacks, set the callback URL to `https://audd.tech/empty/` for the interface to work properly.)

**Please note that all the API requests require the api_token from the Dashboard to be specified as either the query parameter or the POST field**. So just send it in all the requests as `api_token`.  

If you change the limit later, the unused amount of time will be applied as a discount.

</div>

<div class="markdown request-section">

### <HttpRequestTitle color="#26cb7c" type="post" class="PostRequestWrapper"></HttpRequestTitle> 2. Set the URL for callbacks
```text
https://api.audd.io/setCallbackUrl/
```

Set the URL for callbacks using the `setCallbackUrl` API method.  
You can change the URL at any time using this method.  
Callbacks are the requests with recognition results our servers will send to your server.

<HttpRequestParameters codeExamples endpoint={"https://api.audd.io/setCallbackUrl/"} parameters={[
	{'name': 'api_token', 	type: 'string', required: true, 	description: 'The token received from the Dashboard', example: 'your api token'},
	{'name': 'url', 		type: 'string', required: true,		description: 'The URL for the callbacks', example: 'https://yourwebsite.com/callbacks_handler/'},
]} exampleResponseDescription="The callback URL is successfully set"
exampleResponse={{"status": "success","result": null}}
/>

(Please set the callback URL to `https://audd.tech/empty/` or other URL that responds 200 OK if you don't have a server for callbacks and want to use [longpolling or the no-code widget](#longpoll-1)).

</div>

<div class="markdown request-section">

### <HttpRequestTitle color="#26cb7c" type="post" class="PostRequestWrapper"></HttpRequestTitle> 3. Add the streams

```text
https://api.audd.io/addStream/
```

Add the streams using the `addStream` API method. By default, we will send new results after songs end playing. See the `callbacks` parameter description if you want to get the results when songs start playing.

<HttpRequestParameters codeExamples endpoint={"https://api.audd.io/addStream/"} parameters={[
	{'name': 'api_token', 	type: 'string',  required: true, 	description: 'The token received from the Dashboard', example: 'your api token'},
	{'name': 'url', 		type: 'string',  required: true,	description: 'The URL of the audio stream', example: 'https://npr-ice.streamguys1.com/live.mp3'},
	{'name': 'radio_id', 	type: 'integer', required: true,	description: 'Any integer that will identify this stream for you', example: '3249'},
	{'name': 'callbacks', 	type: 'string',	description: <div>By default, callbacks are sent after the song ended playing and contain the total streamed time of the song. Set this parameter to <code>before</code>, if you want to <b>receive the callbacks as soon as a song starts playing</b> (instead of when it finishes). <i>Note that with </i><code>callbacks=before</code><i>, you won't receive the total played time in the callbacks.</i></div>},
]} exampleResponseDescription="The stream is successfully added"
exampleResponse={{"status": "success","result": null}}
/>

<p />

</div>

:::info

As the URL of the audio stream, you can simply send the URL of a stream, like *https://npr-ice.streamguys1.com/live.mp3*. We support most of the stream formats, including DASH, Icecast, HLS, m3u/m3u8.

We also natively support Twitch broadcasts and YouTube live streams, and you can send twitch:\[channel name], youtube:\[video id], and youtube-ch:\[channel id] as the URL - like *twitch:monstercat* for [twitch.tv/monstercat](https://www.twitch.tv/monstercat), *youtube:5qap5aO4i9A* for [youtube.com/watch?v=5qap5aO4i9A](https://www.youtube.com/watch?v=5qap5aO4i9A), or *youtube-ch:UC3zwjSYv4k5HKGXCHMpjVRg* for the current live stream on [youtube.com/channel/UC3zwjSYv4k5HKGXCHMpjVRg](https://www.youtube.com/channel/UC3zwjSYv4k5HKGXCHMpjVRg).

:::

<div class="markdown request-section">

### 4. Receive the results

#### Using callbacks

Receiving the results in callbacks is the recommended method.  
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 notifications.

- The results contain the identified songs.
- Notifications are information about problems with 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. There are 3 codes: `0` (which means that everything's fine), `650` (which means that we can't connect to the stream) and `651` (which means that we don't receive any music from the stream, only white noise). Notifications also contain the time of sending. 

<div className="request-info-body"><Tabs
  defaultValue="with_result"
  values={[
    { label: 'Callback with a result', value: 'with_result', },
    { label: 'Callback with a notification', value: 'with_notification', },
  ]
}>
<TabItem value="with_result"><Response exampleResponse={{"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"}]}}} /></TabItem>
<TabItem value="with_notification"><Response exampleResponse={{"status": "-","notification": {"radio_id": 3,"stream_running": false,"notification_code": 650,"notification_message": "Recognition failed: can't connect to the audiostream"},"time":1587939136}} /></TabItem>
</Tabs></div>
<br />

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 of 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](http://en.wikipedia.org/wiki/Token_bucket) of 15).

**Contact us to receive ISRCs, UPCs and other additional metadata (e.g., from Apple Music, Spotify, MusicBrainz).**

Note that for uploaded catalogs, you'll only receive the unique track ID you sent when you uploaded the matched song; other details won't be available.

#### LongPoll

You can use long polling instead of or together with receiving callbacks. See the [LongPoll section](#longpoll-1) for more info.

For it to work, if you're not planning to receive callbacks, set the callback URL to `https://audd.tech/empty/` using the web interface. (You have to have some callback URL, or you won't be able to retrieve results using long polling.)

#### Manually download results

This is not recommended, but the last 40 results should usually be available for download using [our web stream management interface](https://audd.io/streams/).

For this to work, if you're not planning to receive callbacks, set the callback URL to `https://audd.tech/empty/` using the web interface.

</div>

## What else can I do?

We have additional methods to manage the streams.

<div class="markdown request-section">

### <HttpRequestTitle color="#26cb7c" type="post" class="PostRequestWrapper">`POST`</HttpRequestTitle> Get the current callback URL

```text
https://api.audd.io/getCallbackUrl/
```

Use the `getCallbackUrl` method to get the current callback URL. You can always change it with the `setCallbackUrl` method.

<HttpRequestParameters codeExamples endpoint={"https://api.audd.io/getCallbackUrl/"} parameters={[
	{'name': 'api_token', 	type: 'string',  required: true, 	description: 'The token received from the Dashboard', example: 'your api token'},
]} exampleResponseDescription="Returns the current callback URL"
exampleResponse={{"status": "success", "result": "https://yourwebsite.com/callbacks_handler/"}}
/>

</div>
<div class="markdown request-section">

### <HttpRequestTitle color="#26cb7c" type="post" class="PostRequestWrapper">`POST`</HttpRequestTitle> Get all the streams

```text
https://api.audd.io/getStreams/
```

Use the `getStreams` method to get all the streams the music is being recognized from.

<HttpRequestParameters codeExamples endpoint={"https://api.audd.io/getStreams/"} parameters={[
	{'name': 'api_token', 	type: 'string',  required: true, 	description: 'The token received from the Dashboard', example: 'your api token'},
]} exampleResponseDescription="Returns the array of all the streams you sent us"
exampleResponse={{"status": "success","result": [{"radio_id": 3249,"url": "https://npr-ice.streamguys1.com/live.mp3","stream_running": true,"longpoll_category": "22cd61d45"},{"radio_id": 5512,"url": "youtube:5qap5aO4i9A","stream_running": true,"longpoll_category": "cb88f0898"},{"radio_id": 5513,"url": "twitch:monstercat","stream_running": true,"longpoll_category": "a16a7dd13"},]}}
/>


</div>
<div class="markdown request-section">

### LongPoll

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.

Please use the longpolling after setting a working callback URL using the [setCallbackUrl](#2-set-the-url-for-callbacks) method; ensure that the callback URL responds with the `200 OK` HTTP status when it receives requests with callbacks. If you don't have a server that can return 200 OK to POST requests, use `https://audd.tech/empty/`.

The long poll address is `https://api.audd.io/longpoll/`. As the subscription category, use the `longpoll_category` field from the [/getStreams](#post-get-all-the-streams) response, or calculate the first nine symbols of `MD5(MD5("your api_token")+"radio_id")`. You can share the categories with your clients or users, but please don't include your API tokens in the client-side software.

If you're making the long poll requests manually, here's an example of a LongPoll URL: `https://api.audd.io/longpoll/?category=92b1cc7f0&timeout=50&since_time=1652123144400`. When you receive a response containing the `timestamp` field, use it as the updated `since_time` for the new request. 

We've implemented long polling clients in our [Golang library](https://github.com/AudDMusic/audd-go) and [Twitch extension (JS)](https://github.com/AudDMusic/twitch-extension).

:::tip HTML Widget

You can also use our widget, `https://widget.audd.tech/?ch=-92b1cc7f0&background&history&shadow`. It's based on the Twitch extension's frontend and shows the last recognized song as well as the history (if you want it to show the history). Use the longpoll category with "-" before it as the `ch` URL parameter. You can also use the URL parameters to get the look you want, e.g. `https://widget.audd.tech/?ch=-92b1cc7f0&black-font`.

:::

You can disable the Long Poll for your streams by adding "disable-lastsong=true" as a parameter to your callback URL (i.e., add `?disable-lastsong=true` or `&disable-lastsong=true` to the URL).

</div>
<div class="markdown request-section">

### <HttpRequestTitle color="#26cb7c" type="post" class="PostRequestWrapper">`POST`</HttpRequestTitle> Update stream URL

```text
https://api.audd.io/setStreamUrl/
```

Use the `setStreamUrl` method to update the URL of a stream.

<HttpRequestParameters codeExamples endpoint={"https://api.audd.io/setStreamUrl/"} parameters={[
	{'name': 'api_token', 	type: 'string',  required: true, 	description: 'The token received from the Dashboard', example: 'your api token'},
	{'name': 'url', 		type: 'string',  required: true,	description: 'The new URL of the audio stream', example: 'youtube:5qap5aO4i9A'},
	{'name': 'radio_id', 	type: 'integer', required: true,	description: 'The integer that identifies this stream', example: '5512'},
]} exampleResponseDescription="The stream URL is successfully set"
exampleResponse={{"status": "success","result": null}}
/>

</div>

<div class="markdown request-section">

### <HttpRequestTitle color="#26cb7c" type="post" class="PostRequestWrapper">`POST`</HttpRequestTitle> Delete a stream

```text
https://api.audd.io/deleteStream/
```

Use the deleteStream method to delete a stream. We'll stop to recognize music from it and forget about it's existence.

<HttpRequestParameters codeExamples endpoint={"https://api.audd.io/deleteStream/"} parameters={[
	{'name': 'api_token', 	type: 'string',  required: true, 	description: 'The token received from the Dashboard', example: 'your api token'},
	{'name': 'radio_id', 	type: 'integer', required: true, 	description: 'The integer that identifies this stream', example: '5511'},
]} exampleResponseDescription="The stream is successfully deleted"
exampleResponse={{"status": "success","result": null}}
/>

</div>

## How to send API requests?

There are Code example tabs in each of the API method descriptions. You can use them as reference.

You can send all the fields as GET URL parameters or as POST form data parameters.

You can also send GET requests, even though it's better to send the parameters in the POST body. Here's an example:  
`https://api.audd.io/getStreams/?api_token=your%20api%20token`  
Just don't forget to url-encode the data.

## Support

Reach out to api@audd.io if you have any questions or need any help.

<!--Here are examples of how to send a request by POST:


<div className="tabs-section"><Tabs
  groupId="languages"
  defaultValue="curl"
  values={[
    { label: 'Curl', value: 'curl', },
    { label: 'PHP', value: 'php', },
    { label: 'Python', value: 'python', },
    { label: 'Go', value: 'go', },
    { label: 'JS', value: 'js', },
    { label: 'NodeJS', value: 'nodejs', },
    { label: 'Java', value: 'java', },
  ]
}>
<TabItem value="curl">

```bash
curl https://api.audd.io/addStream/ \
    -F url='https://npr-ice.streamguys1.com/live.mp3' \
    -F radio_id='3249' \
    -F api_token='your api token'
```

</TabItem>
<TabItem value="php">

```php
<?php
$data = [
    'url' => 'https://npr-ice.streamguys1.com/live.mp3',
    'radio_id' => '3249',
    'api_token' => 'your api token',
];
$ch = curl_init();
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_URL, 'https://api.audd.io/addStream/');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
$result = curl_exec($ch);
curl_close($ch);
echo $result;
```

</TabItem>
<TabItem value="python">

```py
data = {
    'url': 'https://npr-ice.streamguys1.com/live.mp3',
    'radio_id': '3249',
    'api_token': 'your api token'
}
result = requests.post('https://api.audd.io/addStream/', data=data)
print(result.text)
```

</TabItem>
<TabItem value="go">

```go
package main

	"fmt"
	"github.com/AudDMusic/audd-go"
	"io/ioutil"
	"net/http"
	"net/url"
)

func main() {
	client := audd.NewClient("your api token")
	Url := "https://npr-ice.streamguys1.com/live.mp3"
	err := client.AddStream(Url, 3249, "", nil)
	if err != nil {
		panic(err)
	}
}
```

</TabItem>
<TabItem value="js">

```javascript
//requires jQuery
var data = {
    'url': 'https://npr-ice.streamguys1.com/live.mp3',
    'radio_id': '3249',
    'api_token': 'your api token'}

$.getJSON('https://api.audd.io/addStream/?jsonp=?', data, function(result){
    console.log(result);
});
```

</TabItem>
<TabItem value="nodejs">

```javascript
var request = require("request");

var data = {
    'url': 'https://npr-ice.streamguys1.com/live.mp3',
    'radio_id': '3249',
    'api_token': 'your api token'
};

request({
    uri: 'https://api.audd.io/addStream/',
    form: data,
    method: 'POST'
  }, function (err, res, body) {
    console.log(body);
});
```

</TabItem>
<TabItem value="java">

```java
// requires OkHttp 
public static void main() {
try {
OkHttpClient client = new OkHttpClient();
RequestBody data = new MultipartBody.Builder().setType(MultipartBody.FORM)
    .addFormDataPart("url", "https://npr-ice.streamguys1.com/live.mp3")
    .addFormDataPart("radio_id", "3249")
    .addFormDataPart("api_token", "your api token").build();
Request request = new Request.Builder().url("https://api.audd.io/addStream/")
    .post(data).build();
Response response = null;
response = client.newCall(request).execute();
String result = null;
result = response.body().string();
System.out.println(result);
} catch (Exception e) {
e.printStackTrace();
}
//Thanks to Yaniv Levy and Adam Cole for the help
```

</TabItem>
</Tabs></div>-->
