Use this API on your own website: show the songs of your music library, let visitors request songs, show the upcoming AutoDJ queue and what is playing now. Every call is a simple POST request (form data, no JSON in the request) and the answer is JSON. Every example below has a short PHP code that you can copy and paste.
sp_api_cached() does this for you). Do not use API calls on your website directly unless your website is protected by Cloudflare.https://YOUR_PANEL_DOMAIN/cp/api.phpPOST (form data) Answer: JSONapi_key and actionSave this code as sp_api.php on your website and replace the URL and the key with your own. Every example in this guide uses it, so you do not have to write the cURL part again. sp_api_cached() remembers an answer for a few seconds, so many visitors share one API call.
<?php
// sp_api.php
define('SP_API_URL', 'https://YOUR_PANEL_DOMAIN/cp/api.php');
define('SP_API_KEY', 'PASTE_YOUR_API_KEY_HERE');
// Sends one call to the API and returns the answer as an array
function sp_api($action, $params = array())
{
$params['api_key'] = SP_API_KEY;
$params['action'] = $action;
$ch = curl_init(SP_API_URL);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($params));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
$body = curl_exec($ch);
curl_close($ch);
$result = json_decode($body, true);
if (!is_array($result)) {
return array('success' => false, 'message' => 'The radio could not be reached.');
}
return $result;
}
// Same as sp_api() but remembers the answer for a few seconds.
// Use it for pages that many visitors open.
function sp_api_cached($action, $params = array(), $seconds = 10)
{
$file = sys_get_temp_dir() . '/sp_api_' . md5($action . serialize($params)) . '.json';
if (is_file($file) && (time() - filemtime($file)) < $seconds) {
$saved = json_decode(file_get_contents($file), true);
if (is_array($saved)) { return $saved; }
}
$result = sp_api($action, $params);
if (!empty($result['success'])) {
file_put_contents($file, json_encode($result));
}
return $result;
}
?>
Every answer is JSON and has a success value. When it is true the call worked and the data is included. When it is false there are an error code and a message in plain English.
// It worked
{ "success": true, ... }
// It did not work
{ "success": false, "error": "invalid_api_key", "message": "The API key is missing or invalid." }
Lists the AutoDJ playlists that contain songs. Use the id of a playlist in the next calls.
| Parameter | Description |
|---|---|
api_key REQUIRED | Your API key. |
action REQUIRED | playlists |
<?php
require 'sp_api.php';
$r = sp_api_cached('playlists', array(), 60);
if ($r['success']) {
foreach ($r['playlists'] as $playlist) {
echo $playlist['id'] . ' - ' . $playlist['name'] . ' (' . $playlist['total'] . ' songs)<br>';
}
}
{
"success": true,
"playlists": [
{ "id": 12, "name": "Pop Hits", "total": 148 },
{ "id": 15, "name": "Rock Classics", "total": 96 }
]
}
Lists the songs (artist and title) of one playlist together with the playlist name. If playlist_id is left out, the whole music library is returned. Long lists are split into pages. The id of a song is what you send in the request call.
| Parameter | Description |
|---|---|
api_key REQUIRED | Your API key. |
action REQUIRED | tracks |
playlist_id optional | Playlist id from the playlists call. Leave out for the whole library. |
page optional | Page number, default 1. |
per_page optional | Songs per page, 1 to 100, default 50. |
<?php
require 'sp_api.php';
$r = sp_api_cached('tracks', array('playlist_id' => 12, 'page' => 1, 'per_page' => 50), 60);
if ($r['success']) {
echo 'Playlist: ' . $r['playlist'] . ' (' . $r['total'] . ' songs)<br>';
foreach ($r['tracks'] as $song) {
echo $song['id'] . ' - ' . $song['artist'] . ' - ' . $song['title'] . '<br>';
}
}
{
"success": true,
"total": 148,
"page": 1,
"per_page": 50,
"playlist_id": 12,
"playlist": "Pop Hits",
"tracks": [
{ "id": 3041, "artist": "Artist Name", "title": "Song Title", "playlist_id": 12, "playlist": "Pop Hits" }
]
}
Finds songs by artist or title. The answer has the same shape as tracks, plus the searched text in q.
| Parameter | Description |
|---|---|
api_key REQUIRED | Your API key. |
action REQUIRED | search |
q REQUIRED | Search text, at least 2 characters. |
playlist_id optional | Search inside one playlist only. |
page / per_page optional | Paging, same as tracks. |
<?php
require 'sp_api.php';
$text = $_GET['q']; // what the visitor typed
$r = sp_api_cached('search', array('q' => $text), 30);
if ($r['success']) {
foreach ($r['tracks'] as $song) {
echo $song['artist'] . ' - ' . $song['title'] . '<br>';
}
} else {
echo $r['message'];
}
Adds the chosen song to the AutoDJ request queue. Send the visitor IP address as visitor_ip so the limits work per visitor and not for your whole website. The AutoDJ must be online. Do not use sp_api_cached() for this call.
| Parameter | Description |
|---|---|
api_key REQUIRED | Your API key. |
action REQUIRED | request |
track_id REQUIRED | The id of a song from tracks or search. |
visitor_ip optional | IP address of your visitor. If left out, the IP address of your web server is used. |
<?php
require 'sp_api.php';
$r = sp_api('request', array(
'track_id' => (int)$_POST['track_id'],
'visitor_ip' => $_SERVER['REMOTE_ADDR'],
));
if ($r['success']) {
echo 'Thank you! Your request is number ' . $r['position'] . ' in the queue.';
} else {
echo $r['message'];
}
{
"success": true,
"message": "Your song request has been added to the queue.",
"track": { "id": 3041, "artist": "Artist Name", "title": "Song Title" },
"position": 2,
"interrupted": false
}
Show the message to your visitor. The limits and the Can Interrupt option are set on the API Information page of your control panel, under Song Request System.
| Message | Meaning |
|---|---|
| Too many song requests. Please try again later. | This visitor reached the request limit per hour. |
| This song was requested recently... | The same song cannot be requested again for a while (song cooldown). |
| The request queue is full... | Too many requests are waiting in the queue. |
| Scheduled playlist is playing and interruption is disabled... | A scheduled playlist is on air and Can Interrupt is off. When it is on, the request is accepted, the scheduled playlist is skipped and interrupted is true. |
| A live DJ is on air... | Requests are not accepted while a live DJ is on air. |
Returns the one song that plays next. song is null when the next song is not known yet. source is request (a visitor asked for it), scheduled (scheduled playlist) or playlist (normal AutoDJ playlist).
| Parameter | Description |
|---|---|
api_key REQUIRED | Your API key. |
action REQUIRED | next_song |
<?php
require 'sp_api.php';
$r = sp_api_cached('next_song', array(), 10);
if ($r['success'] && $r['song']) {
echo 'Up next: ' . $r['song']['artist'] . ' - ' . $r['song']['title'];
} else {
echo 'The next song is not known yet.';
}
{
"success": true,
"song": { "position": 1, "artist": "Artist Name", "title": "Song Title", "source": "playlist" }
}
Returns the next 5 songs in playing order. Song requests come first, then scheduled items, then the AutoDJ playlist.
| Parameter | Description |
|---|---|
api_key REQUIRED | Your API key. |
action REQUIRED | next_songs |
<?php
require 'sp_api.php';
$r = sp_api_cached('next_songs', array(), 10);
if ($r['success']) {
foreach ($r['queue'] as $song) {
echo $song['position'] . '. ' . $song['artist'] . ' - ' . $song['title'] . '<br>';
}
}
{
"success": true,
"queue": [
{ "position": 1, "artist": "Artist Name", "title": "Song Title", "source": "request" },
{ "position": 2, "artist": "Another Artist", "title": "Another Song", "source": "playlist" }
]
}
The same as next_songs, but you choose how many songs you want.
| Parameter | Description |
|---|---|
api_key REQUIRED | Your API key. |
action REQUIRED | queue |
limit optional | Number of songs, 1 to 10, default 5. |
<?php
require 'sp_api.php';
$r = sp_api_cached('queue', array('limit' => 8), 10);
if ($r['success']) {
foreach ($r['queue'] as $song) {
echo $song['artist'] . ' - ' . $song['title'] . '<br>';
}
}
Returns the public details of your radio: name, genre, bitrate, stream port and the ready-to-use stream address. Use it to build a player without typing the port by hand. It always answers for the radio the API key belongs to, a key can never read another radio. Passwords are never returned. This call works even when the AutoDJ is offline.
| Parameter | Description |
|---|---|
api_key REQUIRED | Your API key. |
action REQUIRED | radio_info |
<?php
require 'sp_api.php';
$r = sp_api_cached('radio_info', array(), 300);
if ($r['success']) {
echo $r['name'] . ' - ' . $r['bitrate'] . ' kbps<br>';
echo '<audio controls src="' . htmlspecialchars($r['stream_url']) . '"></audio>';
}
{
"success": true,
"name": "My Radio",
"genre": "Pop",
"website": "https://www.example.com",
"server_type": "shoutcast",
"server_version": "2.6",
"bitrate": 128,
"max_listeners": 100,
"port": 8000,
"ssl_port": 8002,
"stream_path": "/stream",
"stream_url": "http://panel.example.com:8000/stream",
"stream_url_secure": "https://panel.example.com:8002/stream",
"autodj_online": true
}
| Field | Description |
|---|---|
name, genre, website | Stream title and genre of the AutoDJ and the website address of the radio (null when not set). |
server_type, server_version | shoutcast or icecast. The version is 1, 2.5 or 2.6 for SHOUTcast (null when not known). |
bitrate, max_listeners | Bitrate in kbps and the listener limit. |
port, ssl_port, stream_path | Stream port, secure stream port and the path of the stream. |
stream_url, stream_url_secure | Ready-to-use stream addresses. The secure one is null when the radio has no secure port. |
autodj_online | true while the AutoDJ is running. |
Returns the song that is on air now and whether a live DJ is on air. The AutoDJ must be online. song can be null when the song cannot be detected.
| Parameter | Description |
|---|---|
api_key REQUIRED | Your API key. |
action REQUIRED | now_playing |
<?php
require 'sp_api.php';
$r = sp_api_cached('now_playing', array(), 10);
if ($r['success'] && $r['song']) {
echo 'Now playing: ' . $r['song']['artist'] . ' - ' . $r['song']['title'];
} else {
echo 'Nothing to show right now.';
}
{
"success": true,
"song": { "artist": "Artist Name", "title": "Song Title", "started_at": "2026/10/14 22:28:05" },
"live": false,
"dj": ""
}
Returns the recently played songs, newest first.
| Parameter | Description |
|---|---|
api_key REQUIRED | Your API key. |
action REQUIRED | song_history |
limit optional | Number of songs, 1 to 50, default 10. |
<?php
require 'sp_api.php';
$r = sp_api_cached('song_history', array('limit' => 10), 30);
if ($r['success']) {
foreach ($r['history'] as $song) {
echo $song['played_at'] . ' - ' . $song['artist'] . ' - ' . $song['title'] . '<br>';
}
}
{
"success": true,
"history": [
{ "artist": "Artist Name", "title": "Song Title", "played_at": "2026-10-14 22:28:05" }
]
}
Returns how many people are listening now (listeners counts connections, unique_listeners counts each person once) and the listeners of each hour today.
| Parameter | Description |
|---|---|
api_key REQUIRED | Your API key. |
action REQUIRED | listeners |
<?php
require 'sp_api.php';
$r = sp_api_cached('listeners', array(), 30);
if ($r['success']) {
echo 'Listening now: ' . $r['listeners'];
}
{
"success": true,
"listeners": 12,
"unique_listeners": 10,
"today_hourly": { "h00": 3, "h01": 1, "h02": 0, ... "h23": 0 }
}
Tells you if a live DJ is on air right now. This call also works when the AutoDJ is offline.
| Parameter | Description |
|---|---|
api_key REQUIRED | Your API key. |
action REQUIRED | live_dj |
<?php
require 'sp_api.php';
$r = sp_api_cached('live_dj', array(), 10);
if ($r['success'] && $r['live']) {
echo 'LIVE now: ' . $r['dj'];
} else {
echo 'AutoDJ is playing.';
}
{ "success": true, "autodj_online": true, "live": true, "dj": "dj_john" }
Starts your AutoDJ. If it is already running, it is restarted.
| Parameter | Description |
|---|---|
api_key REQUIRED | Your API key. |
action REQUIRED | start_autodj |
<?php
require 'sp_api.php';
$r = sp_api('start_autodj');
echo $r['message'];
{ "success": true, "message": "AutoDJ started.", "restarted": false }
Stops your AutoDJ.
| Parameter | Description |
|---|---|
api_key REQUIRED | Your API key. |
action REQUIRED | stop_autodj |
<?php
require 'sp_api.php';
$r = sp_api('stop_autodj');
echo $r['message'];
{ "success": true, "message": "AutoDJ stopped." }
Returns all DJ accounts of your radio with their permissions. Passwords are never returned.
| Parameter | Description |
|---|---|
api_key REQUIRED | Your API key. |
action REQUIRED | list_dj |
<?php
require 'sp_api.php';
$r = sp_api('list_dj');
if ($r['success']) {
foreach ($r['djs'] as $dj) {
echo $dj['username'] . '<br>';
}
}
{
"success": true,
"total": 1,
"djs": [
{ "username": "dj_john", "canlogin": "yes", "canstream": "yes", "canplayjingles": "yes", "canuploadpic": "yes",
"canusevoice": "no", "canchangepass": "no", "canstartrad": "no", "canstartdj": "no", "canskip": "no" }
]
}
Creates a new DJ account. Permissions are optional (yes or no), the defaults are listed in the permissions table below.
| Parameter | Description |
|---|---|
api_key REQUIRED | Your API key. |
action REQUIRED | add_dj |
dj_username REQUIRED | 3 to 32 characters: letters, numbers, underscore and dot. |
dj_pass REQUIRED | 4 to 64 characters. |
canlogin ... canskip optional | Any DJ permission, see the table below. |
<?php
require 'sp_api.php';
$r = sp_api('add_dj', array(
'dj_username' => 'dj_john',
'dj_pass' => 'S3cretPass',
'canstream' => 'yes',
'canskip' => 'no',
));
echo $r['message'];
{ "success": true, "message": "DJ account created.", "dj": { "username": "dj_john", "canstream": "yes", ... } }
Changes the password and/or permissions of a DJ account. Send only the fields you want to change.
| Parameter | Description |
|---|---|
api_key REQUIRED | Your API key. |
action REQUIRED | update_dj |
dj_username REQUIRED | The DJ account to change. |
dj_pass optional | New password, 4 to 64 characters. |
canlogin ... canskip optional | Any DJ permission, see the table below. |
<?php
require 'sp_api.php';
$r = sp_api('update_dj', array(
'dj_username' => 'dj_john',
'dj_pass' => 'NewS3cretPass',
'canskip' => 'yes',
));
echo $r['message'];
{ "success": true, "message": "DJ account updated." }
Permanently deletes a DJ account.
| Parameter | Description |
|---|---|
api_key REQUIRED | Your API key. |
action REQUIRED | delete_dj |
dj_username REQUIRED | The DJ account to delete. |
<?php
require 'sp_api.php';
$r = sp_api('delete_dj', array('dj_username' => 'dj_john'));
echo $r['message'];
{ "success": true, "message": "DJ account deleted." }
You can send any of these when you add or update a DJ. The default is used when you do not send it.
| Parameter | Default | The DJ can |
|---|---|---|
canlogin | yes | Log in to the DJ panel. |
canstream | yes | Stream live to the radio. |
canplayjingles | yes | Play jingles. |
canuploadpic | yes | Upload a profile picture. |
canusevoice | no | Use the voice (microphone mix) feature. |
canchangepass | no | Change their own password. |
canstartrad | no | Start and stop the radio. |
canstartdj | no | Start and stop the AutoDJ. |
canskip | no | Skip the current song. |
A complete radio website: live player with album covers, now playing, next song and song requests with playlists. Open API Information > Radio Website in your control panel, check the radio name and press Download Website (.zip). Your API address and API key are already written inside, so you only have to upload the files to your website.
| Step | What to do |
|---|---|
| 1 | Upload everything in the zip file to your website (the main folder or a sub folder). Your hosting needs PHP 8.1 or newer with the curl extension. |
| 2 | Make the folder inc/cache writable by PHP (for example permission 755 or 775). |
| 3 | Open the website. The name, API address and API key are already set in inc/config.php. You can also write your own stream address there with stream_url. |
| 4 | Nginx users: .htaccess files are not used. Block the web address /inc/ in your server configuration. |
inc/config.php.When success is false, read the message.
| Message | What to do |
|---|---|
| The API key is missing or invalid. | Check that you copied the full key from the API Information page. If you regenerated the key, use the new one. |
| Only POST requests are accepted. | Use the helper file from this guide, it sends the call in the right way. |
| AutoDJ is currently offline. | Start your AutoDJ from the panel or with the start_autodj call. |
| AutoDJ is not available for this account. | Your hosting package does not include AutoDJ. |
| Too many requests... is blocked for 10 minute(s). | Your website calls the API too often. Wait 10 minutes and use sp_api_cached() so visitors share one answer. |
| The radio could not be reached. | Check the API URL in sp_api.php. |