Radio Client API (PHP & JSON)

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.

Requirements & Rate Limits:
  • The API is available for radios that have AutoDJ. Song request and queue calls work while the AutoDJ is online.
  • Get your API Endpoint URL and API Key from API Information in the left menu of your control panel. The key is created the first time you open that page.
  • Security: Keep your API key private. Use it only in PHP files on your server, never in JavaScript or in HTML that visitors can see. If the key leaks, press Regenerate Key on the API Information page.
  • Do not call the API on every page view. Ask it once every few seconds and show the saved result to everyone (sp_api_cached() does this for you). Do not use API calls on your website directly unless your website is protected by Cloudflare.
  • More than 120 calls per minute with the same API key blocks the key for 10 minutes.
  • More than 10 wrong API keys per minute from the same IP address blocks that IP address for 10 minutes.
API Endpoint: https://YOUR_PANEL_DOMAIN/cp/api.php
Method: POST (form data)   Answer: JSON
Every call sends: api_key and action
Getting Started
Get your API key, copy the helper file once and use it in every example.
Helper sp_api.php PHP Helper

Save 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.

sp_api.php
<?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;
}
?>
Info Response format

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.

Example
// It worked
{ "success": true, ... }

// It did not work
{ "success": false, "error": "invalid_api_key", "message": "The API key is missing or invalid." }
Song Request System
Show the music library, let visitors search and pick a song and send the request to the AutoDJ.
POST Action: playlists

Lists the AutoDJ playlists that contain songs. Use the id of a playlist in the next calls.

ParameterDescription
api_key REQUIREDYour API key.
action REQUIREDplaylists
PHP Example
<?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>';
    }
}
Response
JSON
{
  "success": true,
  "playlists": [
    { "id": 12, "name": "Pop Hits", "total": 148 },
    { "id": 15, "name": "Rock Classics", "total": 96 }
  ]
}
POST Action: tracks

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.

ParameterDescription
api_key REQUIREDYour API key.
action REQUIREDtracks
playlist_id optionalPlaylist id from the playlists call. Leave out for the whole library.
page optionalPage number, default 1.
per_page optionalSongs per page, 1 to 100, default 50.
PHP Example
<?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>';
    }
}
Response
JSON
{
  "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" }
  ]
}
POST Action: request

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.

ParameterDescription
api_key REQUIREDYour API key.
action REQUIREDrequest
track_id REQUIREDThe id of a song from tracks or search.
visitor_ip optionalIP address of your visitor. If left out, the IP address of your web server is used.
PHP Example
<?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'];
}
Response
JSON
{
  "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
}
When a request is refused

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.

MessageMeaning
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.
Upcoming AutoDJ Queue
Show the songs that will play next. The AutoDJ must be online.
POST Action: next_song

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).

ParameterDescription
api_key REQUIREDYour API key.
action REQUIREDnext_song
PHP Example
<?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.';
}
Response
JSON
{
  "success": true,
  "song": { "position": 1, "artist": "Artist Name", "title": "Song Title", "source": "playlist" }
}
POST Action: next_songs

Returns the next 5 songs in playing order. Song requests come first, then scheduled items, then the AutoDJ playlist.

ParameterDescription
api_key REQUIREDYour API key.
action REQUIREDnext_songs
PHP Example
<?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>';
    }
}
Response
JSON
{
  "success": true,
  "queue": [
    { "position": 1, "artist": "Artist Name", "title": "Song Title", "source": "request" },
    { "position": 2, "artist": "Another Artist", "title": "Another Song", "source": "playlist" }
  ]
}
POST Action: queue

The same as next_songs, but you choose how many songs you want.

ParameterDescription
api_key REQUIREDYour API key.
action REQUIREDqueue
limit optionalNumber of songs, 1 to 10, default 5.
PHP Example
<?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>';
    }
}
Radio Information
Public details of your radio and the ready-to-use stream address.
POST Action: radio_info

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.

ParameterDescription
api_key REQUIREDYour API key.
action REQUIREDradio_info
PHP Example
<?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>';
}
Response
JSON
{
  "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
}
FieldDescription
name, genre, websiteStream title and genre of the AutoDJ and the website address of the radio (null when not set).
server_type, server_versionshoutcast or icecast. The version is 1, 2.5 or 2.6 for SHOUTcast (null when not known).
bitrate, max_listenersBitrate in kbps and the listener limit.
port, ssl_port, stream_pathStream port, secure stream port and the path of the stream.
stream_url, stream_url_secureReady-to-use stream addresses. The secure one is null when the radio has no secure port.
autodj_onlinetrue while the AutoDJ is running.
Now Playing and Statistics
What is on air, recent songs, listeners and live DJ status.
POST Action: now_playing

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.

ParameterDescription
api_key REQUIREDYour API key.
action REQUIREDnow_playing
PHP Example
<?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.';
}
Response
JSON
{
  "success": true,
  "song": { "artist": "Artist Name", "title": "Song Title", "started_at": "2026/10/14 22:28:05" },
  "live": false,
  "dj": ""
}
POST Action: song_history

Returns the recently played songs, newest first.

ParameterDescription
api_key REQUIREDYour API key.
action REQUIREDsong_history
limit optionalNumber of songs, 1 to 50, default 10.
PHP Example
<?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>';
    }
}
Response
JSON
{
  "success": true,
  "history": [
    { "artist": "Artist Name", "title": "Song Title", "played_at": "2026-10-14 22:28:05" }
  ]
}
POST Action: listeners

Returns how many people are listening now (listeners counts connections, unique_listeners counts each person once) and the listeners of each hour today.

ParameterDescription
api_key REQUIREDYour API key.
action REQUIREDlisteners
PHP Example
<?php
require 'sp_api.php';

$r = sp_api_cached('listeners', array(), 30);

if ($r['success']) {
    echo 'Listening now: ' . $r['listeners'];
}
Response
JSON
{
  "success": true,
  "listeners": 12,
  "unique_listeners": 10,
  "today_hourly": { "h00": 3, "h01": 1, "h02": 0, ... "h23": 0 }
}
POST Action: live_dj

Tells you if a live DJ is on air right now. This call also works when the AutoDJ is offline.

ParameterDescription
api_key REQUIREDYour API key.
action REQUIREDlive_dj
PHP Example
<?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.';
}
Response
JSON
{ "success": true, "autodj_online": true, "live": true, "dj": "dj_john" }
AutoDJ Control
Start or stop the AutoDJ. These calls do not need the AutoDJ to be online.
POST Action: start_autodj

Starts your AutoDJ. If it is already running, it is restarted.

ParameterDescription
api_key REQUIREDYour API key.
action REQUIREDstart_autodj
PHP Example
<?php
require 'sp_api.php';

$r = sp_api('start_autodj');

echo $r['message'];
Response
JSON
{ "success": true, "message": "AutoDJ started.", "restarted": false }
POST Action: stop_autodj

Stops your AutoDJ.

ParameterDescription
api_key REQUIREDYour API key.
action REQUIREDstop_autodj
PHP Example
<?php
require 'sp_api.php';

$r = sp_api('stop_autodj');

echo $r['message'];
Response
JSON
{ "success": true, "message": "AutoDJ stopped." }
Use the start and stop calls only from a private page that you protect with a password. Never put them on a public page.
DJ Accounts
DJ accounts are the logins your DJs use to connect to your radio live. DJ usernames and passwords must be unique on the server.
POST Action: list_dj

Returns all DJ accounts of your radio with their permissions. Passwords are never returned.

ParameterDescription
api_key REQUIREDYour API key.
action REQUIREDlist_dj
PHP Example
<?php
require 'sp_api.php';

$r = sp_api('list_dj');

if ($r['success']) {
    foreach ($r['djs'] as $dj) {
        echo $dj['username'] . '<br>';
    }
}
Response
JSON
{
  "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" }
  ]
}
POST Action: add_dj

Creates a new DJ account. Permissions are optional (yes or no), the defaults are listed in the permissions table below.

ParameterDescription
api_key REQUIREDYour API key.
action REQUIREDadd_dj
dj_username REQUIRED3 to 32 characters: letters, numbers, underscore and dot.
dj_pass REQUIRED4 to 64 characters.
canlogin ... canskip optionalAny DJ permission, see the table below.
PHP Example
<?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'];
Response
JSON
{ "success": true, "message": "DJ account created.", "dj": { "username": "dj_john", "canstream": "yes", ... } }
POST Action: update_dj

Changes the password and/or permissions of a DJ account. Send only the fields you want to change.

ParameterDescription
api_key REQUIREDYour API key.
action REQUIREDupdate_dj
dj_username REQUIREDThe DJ account to change.
dj_pass optionalNew password, 4 to 64 characters.
canlogin ... canskip optionalAny DJ permission, see the table below.
PHP Example
<?php
require 'sp_api.php';

$r = sp_api('update_dj', array(
    'dj_username' => 'dj_john',
    'dj_pass'     => 'NewS3cretPass',
    'canskip'     => 'yes',
));

echo $r['message'];
Response
JSON
{ "success": true, "message": "DJ account updated." }
POST Action: delete_dj

Permanently deletes a DJ account.

ParameterDescription
api_key REQUIREDYour API key.
action REQUIREDdelete_dj
dj_username REQUIREDThe DJ account to delete.
PHP Example
<?php
require 'sp_api.php';

$r = sp_api('delete_dj', array('dj_username' => 'dj_john'));

echo $r['message'];
Response
JSON
{ "success": true, "message": "DJ account deleted." }
Info DJ permissions

You can send any of these when you add or update a DJ. The default is used when you do not send it.

ParameterDefaultThe DJ can
canloginyesLog in to the DJ panel.
canstreamyesStream live to the radio.
canplayjinglesyesPlay jingles.
canuploadpicyesUpload a profile picture.
canusevoicenoUse the voice (microphone mix) feature.
canchangepassnoChange their own password.
canstartradnoStart and stop the radio.
canstartdjnoStart and stop the AutoDJ.
canskipnoSkip the current song.
Radio Website
A ready-made radio website that uses this API.
Download Ready-made radio website

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.

StepWhat to do
1Upload 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.
2Make the folder inc/cache writable by PHP (for example permission 755 or 775).
3Open 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.
4Nginx users: .htaccess files are not used. Block the web address /inc/ in your server configuration.
Keep the package private. It contains your API key. If the key ever leaks, press Regenerate Key on the API Information page and write the new key into inc/config.php.
Troubleshooting
Most common messages and what to do.
Info Common messages

When success is false, read the message.

MessageWhat 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.