Radio Cult API reference

Introduction

Are you looking to power your online radio station's website with the Radio Cult API? If so, you're in the right place.

The Radio Cult API is organised around REST. We expose many of our endpoints, both read and write, so you easily can power your site, workflows and automations.

Our endpoints return JSON-encoded responses and standard HTTP response codes.

Your API key is used to authenticate your requests and prove you have the requisite access. Make sure to follow proper security protocols with your API key. You can roll your API key whenever you want, in case of a breach.

Not a developer?

You can easily integrate Radio Cult functionality into your site using our range of embeds - such as our chat rooms, weekly schedule and player components.

Don't have an account yet?

You need to create a Radio Cult account before you can power your station with our APIs. Go to our sign up page to get started!

Why the Radio Cult API?

If you're already managing your internert radio station data through Radio Cult, why take the extra step of using an external Content Management System (CMS) when you can just use Radio Cult as a CMS?

Not only can you manage all your data on the Radio Cult platform - like your artist profiles and schedules - you can also fetch this data to display on your site. Radio Cult is the one-stop shop for your station.

Getting started

To get started using our API you need to create an API key first. The API key allows you to access all our APIs by proving you are who you say you are. Afterall, we only want you to be able to access your station data.

API keys

Generating an API key

To generate an API key for your station, simply head over to the API key settings page. On this page you will be able to generate new secret and publishable API keys. You can delete or roll API keys at any point.

Your station ID

You will also be able to find your unique stationId on the API key settings page. You will need to use your stationId to build the correct URLs for our REST API.

Publishable vs secret keys

Public key

Publishable keys are used to access read-only endpoints. This means there is limited access if your key gets leaked.

In short, this means you're safe to use your publishable keys on your website.

If you wish to block access in the future then simply delete or roll your publishable key.

A publishable API key should look something like: pk_34c9a89dd5434676972834781b55ad40

Secret key

Secret keys allow access to all API endpoints, including endpoints that modify your station's data. For example, uploading media, creating artists and more.

Due to the expanded access of secret keys, you should take precautions to prevent your secret key from being leaked (hence, the wonderfully apt name of a "secret" key).

You will most likely be using your secret key in your backend or as part of a CLI workflow. You should not use your secret key on your website.

If you wish to access read-only data, then you should use a publishable key, which can be safely stored and used in your frontend code.

A secret API key should look something like: sk_34c9a89dd5434676972834781b55ad40s78ahddha6884

Using your API key

Once you have your API key is is simple to use it. Simply include the API key in the x-api-key header on all requests to our API.

The x-api-key header value can be a publishable or a secret key. Use the correct API key for the endpoint in question.

In general, use a publishable API key for all GET requests. Use a secret key for any PUT, POST or DELETE requests.

An example of using your API key
fetch('https://api.radiocult.fm/api/station/:stationId/artists', {
  headers: {
    'x-api-key': <your_api_key_here>,
  },
});

API URL

The URL to use for all API endpoints is https://api.radiocult.fm. Make sure to direct requests there rather than the normal Radio Cult URL.

Radio Cult API URL
'https://api.radiocult.fm'

Errors

The Radio Cult API uses conventional HTTP response codes to indicate the success or failure of each request.

In general: response status codes in the 2xx range indicate success. 4xx response codes indicate an error due to invalid information provided to the endpoint (e.g., missing or incorrect parameters). 5xx response codes indicate an error with our servers, and not your request (these are rare, if this does happen then we will have been alerted and on the case but feel free to reach out as well).

We try to be consistent with return values. In the case of an error, every reponse body should be an object containing at least the property success which will be set to false.

Error response
{
    success: false,
    error?: string
}

API routes

Below you will find an overview of all the API routes you can query to power your site and internal tools, along with an explanation of the objects and entities returned.

Artists

The Artist object represents an instance of an artist (or presenter, or host, or whatever language you choose) in Radio Cult. An Artist is someone who presents shows on your station.

An Artist encapsulates the common information for a host or presenter - such as name, description, social media links and more.

As Artists can be assigned to shows, you can fetch all shows an Artist is on via their ID. Additionally, Events will have the ID for any Artist on that show.

Endpoints
GET  /api/station/:stationId/artists
GET  /api/station/:stationId/artists/:artistId
GET  /api/station/:stationId/artists/:slug
POST /api/station/:stationId/artists
GET  /api/station/:stationId/artists/:artistId/schedule?startDate=<iso_timestamp>&endDate=<iso_timestamp>

The Artist object

Attributes

idstring

The unique ID of the artist

namestring

The name of the artist. As you can create an artist with only an email, it is possible for this value to not be set

stationIdstring

The unique ID of the station that the artist belongs to

slugstring

An alternative and human-readable ID of the artist

socialsmap

Map containing socials related to the artist - e.g. twitter handle, website. This can be undefined, as can the properties within

shareableLinkIdstring

The shareable Link that gives 3rd parties editable access to the artist. This may be useful if you are building an internal tool for your station. You most likely will not want to render this on any public facing site.

descriptionJSONContent | undefined

The artists description represented in TipTap JSON format

logomap

The artwork for the artist. If no artwork has been uploaded then this may be undefined. Once artwork has been uploaded it is automatically resized. The resizing happens asynchronously. As such, there is a possibility that any of the resize values may be undefined for a few seconds after the image has been uploaded. The time window is so small that you will be very unlikely to ever run into this.

tagsArray<string>

A string array containing the tags assigned to the artist

genresArray<string>

A string array containing the genres of the artist

modifiedstring [UTC timestamp]

A UTC timestamp of when the artist was last modified/updated

createdstring [UTC timestamp]

A UTC timestamp of when the artist was created

The artist object
{
    id: string;
    name?: string;
    stationId: string; 
    slug?: string;
    socials?: {
      twitterHandle?: string;
      instagramHandle?: string;
      facebook?: string;
      mixcloud?: string;
      soundcloud?: string;
      site?: string;
    };
    shareableLinkId: string;
    description?: JSONContent | undefined;
    logo?:  {
        default: string;
        '1024x1024': string;
        '32x32'?: string;
        '64x64'?: string;
        '128x128'?: string;
        '256x256'?: string;
        '512x512'?: string;
    };
    tags: Array<string>;
    genres: Array<string>;
    modified: string;
    created: string;
}

Retrieve all artists

Call the get all artists endpoint to return all of your artists.

Endpoint
GET /api/station/:stationId/artists
Response
{
  success: true,
  artists: Array<Artist>
} 

Retrieve an artist by ID

Use an artist's ID to fetch their details.

Use your station ID and the ID of the artist you are interested in to build the URL.

Endpoint
GET /api/station/:stationId/artists/:artistId
Response
{
  success: true,
  artist: Artist
} 

Retrieve an artist by slug

Use an artist's slug to fetch their details.

Use your station ID and the slug of the artist you are interested in to build the URL.

Endpoint
GET /api/station/:stationId/artists/:slug
Response
{
  success: true,
  artist: Artist
} 

Retrieve an artist's schedules

Use an Artist's ID to fetch all events between the specified start and end dates the artist has been assigned to. The events will be returned sorted by start time.

startDate and endDate are required query params. They must be present for the endpoint to return successfully.

Endpoint
GET /api/station/:stationId/artists/:artistId/schedule?startDate=<iso_timestamp>&endDate=<iso_timestamp>
Query params (* required)
startDate*: ISO_Timestamp (the beginning of the range you want events within)
endDate*: ISO_Timestamp (the end of the range you want eventswithin)
Response
{
  schedules: Array<Event>,
  success: true,
}

Create an artist

Create a new artist.

Use your station's ID to build the URL.

You must provide either email or name in the request body to create an artist. If an email is provided, then it must be a valid email address.

If provided, site must be a valid URL.

Lastly, if provided, description must either be a string or TipTap JSON format

Endpoint
POST /api/station/:stationId/artists
Body (JSON)
{
    name?: string,
    email: string,
    slug?: string,
    site?: string,
    twitterHandle?: string,
    instagramHandle?: string,
    facebook?: string,
    mixcloud?: string,
    soundcloud?: string,
    description?: string | JSONContent,
    tags?: string[],
    genres?: string[],
} |
{
    name: string,
    email?: string,
    slug?: string,
    site?: string,
    twitterHandle?: string,
    instagramHandle?: string,
    facebook?: string,
    mixcloud?: string,
    soundcloud?: string,
    description?: string | JSONContent,
    tags?: string[],
    genres?: string[],
}
Response
{
  success: true,
  artist: Artist
} 

Schedule

The schedule endpoints can be used to work out what is playing on your stream now and what events are scheduled for the future.

You'll generally query the live now endpoint to build custom players and display what is currently being played on your stream. You'll want to use the range endpoint for building Schedule pages, displaying upcoming events for the week.

These endpoints will return Events. The Event object represents an instance of an scheduled event.

Endpoints
GET /api/station/:stationId/schedule?startDate=<iso_timestamp>&endDate=<iso_timestamp>
GET /api/station/:stationId/schedule/live

The Event object

Attributes

idstring

The unique ID of the event

stationIdstring

The unique ID of the station that the event belongs to

titlestring

The title of the event

startDateUtcstring [UTC timestamp]

The start date of the event formatted as a ISO timestamp

endDateUtcstring [UTC timestamp]

The end date of the event formatted as a ISO timestamp

descriptionJSONContent | undefined

The event description represented in TipTap JSON format

durationMinutes (number)

The duration of the event expressed as minutes

timezonestring

The original timezone the event was created in

colorstring | undefined

The color of the event as a hex code

mediastring

The media attached to an event. Media can either be live, a mix or a playlist.

artistIdsArray<string> | undefined

An optional array of the IDs of artists attached to an event

isRecurringboolean

A boolean value indicating whether the event is standalone (i.e. doesn't repeat) or is repeating (i.e. is part of a series of events)

modifiedstring [UTC timestamp]

A UTC timestamp of when the event was last modified/updated.

createdstring [UTC timestamp]

A UTC timestamp of when the event was created.

The event object
{
    id: string;
    stationId: string;
    title: string;
    startDateUtc: string;
    endDateUtc: string;
    description?: JSONContent;
    duration: Minutes;
    timezone: string;
    color?: string;
    artistIds?: string[];
    isRecurring: boolean
    media: 
      | {
        type: 'mix';
        trackId?: string | undefined;
      }
      | {
          type: 'playlist';
          playlistId: string;
        }
      | {
          type: 'live';
        };
}

Retrieve live now

Call the get live now endpoint to return what is currently playing.

This endpoint will return the "status" of your stream and the content being played. The "status" can be one of three things - either:

  1. schedule - which means a scheduled event is playing,
  2. offAir - which means your stream is off air and nothing is playing, or
  3. defaultPlaylist - which means there is no scheduled event and your default playlist is playing.

The content of the stream can be an Event (in the case of a scheduled show), an Off Air enum to indicate the stream is off air or the details associated with your default playlist.

The endpoint also returns the Metadata of the track details currently being played on the stream. See below for more details on the shape of the Metadata object.

Endpoint
GET /api/station/:stationId/schedule/live
Response
{
  success: true;
  result:
    | { status: 'schedule'; content: Event; metadata: Metadata }
    | { status: 'offAir'; content: 'Off Air'; metadata: Metadata }
    | {
        status: 'defaultPlaylist';
        content: {
          name: string;
          numberOfSongs: number;
          duration: Minutes;
        };
        metadata: Metadata
  };
}

The Metadata object

titlestring

The title of the current song (or, potentially, the metadata pushed via your live streaming client)

filenamestring

The filename of the current song

durationnumber (Seconds)

The duration of the current song in seconds

albumstring | undefined

The album of the current song

artiststring | undefined

The artist of the current song

playoutStartUnixTimestampnumber (unix timestamp)

The unix timestamp of when the current song started playing

playoutStartIsoTimestampstring (ISO timestamp)

The ISO timestamp of when the current song started playing

artworkmap | undefined

The artwork for the current song. If no artwork has been uploaded then this may be undefined. Once artwork has been uploaded it is automatically resized. The resizing happens asynchronously. As such, there is a possibility that any of the resize values may be undefined for a few seconds after the image has been uploaded. The time window is so small that you will be very unlikely to ever run into this.

Metadata
type Metadata = {
  title: string;
  filename: string;
  duration: Seconds;
  album: string | undefined;
  artist: string | undefined;
  playoutStartUnixTimestamp: number;
  playoutStartIsoTimestamp: string;
  artwork: {
    original?: string;
    default?: string;
    '32x32'?: string;
    '64x64'?: string;
    '128x128'?: string;
    '256x256'?: string;
    '512x512'?: string;
  } | undefined;
}

Retrieve events in date range

Call the get events in range endpoint to return all events between specified start and end dates. The events will be returned sorted by start time.

startDate and endDate are required query params. They must be present for the endpoint to return successfully.

Endpoint
GET /api/station/:stationId/schedule?startDate=<iso_timestamp>&endDate=<iso_timestamp>
Query params (* required)
startDate*: ISO_Timestamp (indicating the beginning of the range you want events for)
endDate*: ISO_Timestamp (indicating the end of the range you want events for)
Response
{
  schedules: Array<Event>,
  success: true,
}

Media

The media endpoints can be used to upload files.

The media endpoints are currently enabled on a case-by-case basis. Please reach out if you wish for the media endpoints to be enabled for your account.

Endpoints
POST /api/station/:stationId/media/track
POST /api/station/:stationId/media/track/:trackId/upload/soundcloud
PUT  /api/station/:stationId/media/track/:trackId/tag/:tagId
POST /api/station/:stationId/media/playlist/:playlistId/entry

Upload a media file

Call the upload endpoint to upload a file to your media library.

This endpoint is useful for building workflows and automating uploads when you have many Artists and shows.

The request takes a form data body, where stationMedia is the file you wish to upload.

The file must be mp3. The file must have a valid duration.

We use the metadata (or file name if metadata is not set) to set the track information.

OPTIONALLY: you can provide metadata overrides in the form data. This will override the metadata we extract from the file.

NOTE: To ensure we can properly validate the metadata overrides, you must attach it to your form data as valid JSON. You need to JSON.stringify the metadata overrides before adding them to the form data.


Example code
import { createReadStream } from 'node:fs';
import FormData from 'form-data';
import { request } from 'undici';

const audioFile = createReadStream(filePath, {
  autoClose: true,
});

const formData = new FormData();
formData.append('stationMedia', audioFile);
formData.append(
  'metadata',
  JSON.stringify({
    title: 'Title',
    album: 'Album',
  })
);

await request(
  `https://api.radiocult.fm/api/station/${stationId}/media/track`,
  {
    method: 'POST',
    body: formData,
    headers: {
      ...formData.getHeaders(),
      'x-api-key': secretKey,
    },
  }
);
Endpoint
POST /api/station/:stationId/media/track
Body (form data)
stationMedia: mp3 file,

// Optional metadata overrides
metadata?: Stringified JSON<{
  title?: string,
  filename?: string,
  album?: string,
  artist?: string,
  isrc?: string,
}>
Response
{
  success: true,
  track: {
    id: string
  }
}

Upload to Soundcloud

Call this endpoint to upload an existing file from your Radio Cult media library to your connected Soundcloud account.

This endpoint is useful for building workflows and automating uploads.

The request takes a form data body. Use the returned id from uploading a track to form the URL.

NOTE: To ensure we can properly validate the input, you must send valid JSON for all fields except artworkData. This means you must JSON.stringify the fields before sending them in the form data.


Example code
  const formData = new FormData();
  formData.append('tags', JSON.stringify(['rock', 'pop']));
  formData.append('title', JSON.stringify('Autumn Mix'));
  formData.append('embeddableBy', JSON.stringify('all'));
  formData.append('sharing', JSON.stringify('public'));
  formData.append('downloadable', String(true));
  formData.append('commentable', String(false));
Endpoint
POST /api/station/:stationId/media/track/:trackId/upload/soundcloud
Body (form data)
title: string,
tags: Array<string>,
embeddableBy: 'all' | 'me' | 'none',
sharing: 'public' | 'private',
downloadable: boolean,
commentable: boolean,
description?: string,
artworkData?: artwork file (max 2MB), 
Response
{
  success: true,
}

Tag a media file

Call this endpoint to add a tag to an uploaded media file.

Use the returned track ID from uploading a file to form the URL.

You can get the ID of a tag from the URL displayed in the tag view. For example, when viewing a tag your browser will display a URL like: https://app.radiocult.fm/tags?tag=2sZyt9DQDz8cLOUvFiZ2xS5MTIi. The tag ID in this case would be 2sZyt9DQDz8cLOUvFiZ2xS5MTIi.

This endpoint is useful for building workflows and automating uploads.

Endpoint
PUT /api/station/:stationId/media/track/:trackId/tag/:tagId
Response
{
  success: true,
}

Add a media file to a playlist

Call this endpoint to add an uploaded media file to a playlist.

Use the returned track ID from uploading a file to form the URL.

You can get the ID of a playlist from the URL displayed in the playlist view. For example, when viewing a playlist your browser will display a URL like: https://app.radiocult.fm/playlists?playlist=2sZyt9DQDz8cLOUvFiZ2xS5MTIi. The playlist ID in this case would be 2sZyt9DQDz8cLOUvFiZ2xS5MTIi.

This endpoint is useful for building workflows and automating uploads.

Endpoint
POST /api/station/:stationId/media/playlist/:playlistId/entry
Body (JSON)
trackId: string
Response
{
  success: true,
}

Tags

The tag endpoints can be used to manage your tags. These endpoints are helpful when building automations and CLI workflows.

Due to the sensitive nature use your Secret Key when calling these endpoints.

Endpoints
GET /api/station/:stationId/media/tag

The Tag object

Attributes

idstring

The unique ID of the tag

stationIdstring

The unique ID of the station that the tag belongs to

namestring

The name of the tag

colorstring [hex code]

The hex color of the tag

The event object
{
    id: string;
    stationId: string;
    name: string;
    color: string;
}

Retrieve all tags

Call the get all tags endpoint to return all of your tags.

Use your Secret Key when accessing this endpoint.

Endpoint
GET /api/station/:stationId/media/tag
Response
{
    success: true,
    tags: Array<Tag>
} 

Playlists

The playlist endpoints can be used to manage your playlists. These endpoints are helpful when building automations and CLI workflows.

Due to the sensitive nature use your Secret Key when calling these endpoints.

Endpoints
GET    /api/station/:stationId/media/playlist
DELETE /api/station/:stationId/media/playlist/:playlistId/entries

The Playlist object

Attributes

idstring

The unique ID of the playlist

stationIdstring

The unique ID of the station that the playlist belongs to

namestring

The name of the playlist

durationSeconds [number]

The duration of the playlist in seconds

playOrderstring

The order in which the playlist entries will play out. Either in order (in_order) or shuffled (shuffle)

numberOfSongsnumber

The total number of entries in the playlist (songs and tags)

numberOfTagsnumber

The total number of tags in the playlist

The event object
{
    id: string;
    stationId: string;
    name: string;
    duration: Seconds;
    playOrder: 'in_order' | 'shuffle'
    numberOfSongs: number;
    numberOfTags: number;
}

Retrieve all playlists

Call the get all playlists endpoint to retrieve a list of all of your playlists.

Use your Secret Key when accessing this endpoint.

Endpoint
GET /api/station/:stationId/media/playlist
Response
{
    success: true,
    playlists: Array<Playlist>
} 

Clear a playlist's entries

Call this endpoint to remove all entries (e.g. songs and tags) from a playlist. This will result in an empty playlist.

This endpoint is useful when automating content for repeating shows.

For example, you can create an event, attach a playlist to the event and make note of the playlist ID. You can then build a workflow where you clear the playlist, upload any new media files and add to the playlist. You have effectively removed the audio for the previous show and prepared the playlist for the next occurrence of the show. All via the API.

Use your Secret Key when accessing this endpoint.

Endpoint
DELETE /api/station/:stationId/media/playlist/:playlistId/entries
Response
{
    success: true,
    playlist: Playlist
} 

Have any questions?

Feel free to reach out if you need a hand! We're more than happy to help explain the API, best practices or even spar a new concept.