API reference

ERICADE Radio API v1 Documentation

Base URL: https://api.ericade.net/ — all v1 endpoints live directly under /radio/. v1 is the original API. New integrations should use the v2 API where an equivalent exists.

Updated: 2026-10-26

Conventions

Unless stated otherwise, every v1 endpoint follows the same pattern:

Response envelope

Endpoints that return data echo their JSON payload directly (for example {"Tracks": [...]}). Endpoints that only perform an action, and every endpoint that fails, return the three-field envelope below.

AttributeDescriptionExample
messageEither Success or Failure.Failure
subcodeMachine-facing description of what the API did internally.FALSE
submessageHuman-facing message suitable for display to the end user.You need to specify a StationID.
{
  "message": "Failure",
  "subcode": "FALSE",
  "submessage": "You need to specify a StationID."
}

Status codes

CodeMeaning
200Success. The body is the endpoint’s payload or the Success envelope.
204Nothing has changed since the Sequence value you sent. Returned by gettrack, songs and listnews. Keep displaying the previously received data.
400Validation failure, missing/incorrect credentials, or a caller outside the allowed IP range. Note that gettrack, songs and checkifexists return their failure envelope with HTTP 200 — always check the message field, not just the status code.
429Rate limited. A Retry-After header gives the number of seconds to wait.
500Fatal server-side error. gettrack and getlistening trap these and still return a valid JSON failure envelope.

Rate limiting

Every v1 endpoint runs the shared API throttle before doing any work. Callers that exceed the configured request count within the configured window are banned for a period and receive:

{
  "message": "Failure",
  "subcode": "Too Many Requests",
  "submessage": "You have been throttled due to too many requests. Please try again in 600 seconds."
}

Station IDs

StationIDStation
1ericade.radio — 24/7 tracked music
2Best of ericade.radio

Authentication

v1 uses two different credential types, depending on whether the endpoint is listener-facing or part of the station ingest chain.

1. JWT token (public endpoints)

Obtain a token by making a GET request to the token endpoint:

GET https://radio.ericade.net/get-token/

The response is a raw JWT string. v1 is inconsistent about which body field carries it — the table below lists the field name each endpoint expects.

2. Shared secret (ingest endpoints)

The station playout software and the stream server authenticate with a pre-shared secret sent in the Password field. These endpoints are additionally restricted to the internal IP ranges configured on the server and are not available to third-party callers.

Credential field per endpoint

EndpointCredentialField name(s)IP restricted
/radio/gettrack/JWTjwt or PasswordNo
/radio/songs/<trackid>/JWTToken or PasswordNo
/radio/listtracks/JWTjwtNo
/radio/listnews/JWTjwtNo
/radio/addnews/JWTjwtNo
/radio/getplayout/JWTPassword or jwtNo
/radio/getstationstats/JWTPassword or jwtNo
/radio/getrequeststats/JWTPasswordNo
/radio/addrequest/JWTPasswordNo
/radio/updatestar/JWTPasswordNo
/radio/getlistening/JWT + administrator’s user tokenPassword, UserTokenNo
/radio/getnowplaying/Shared secretPassword (query string)Yes
/radio/getnextrequest/Shared secretPasswordYes
/radio/updateplayedrequest/Shared secretPasswordYes
/radio/checkifexists/Shared secretPasswordYes
/radio/updatetrack/Shared secretPasswordYes
/radio/updatestreamevent/Shared secretPasswordYes
Token replay protection is currently disabled, but reusing tokens across sessions is still inadvisable.

Get Track

The workhorse of v1. Depending on which fields you send it returns the currently playing track, one specific track, or a set of search results. This single endpoint is what v2 split into nowplaying, songs and search.

POST https://api.ericade.net/radio/gettrack/

Modes

The mode is selected by the combination of fields you send, evaluated in this order:

ModeTriggered byReturns
Now playingNowPlaying=1The track currently on air on the station, with buffer compensation applied.
Tag searchSearch starting with Tags: or tag:All tracks whose tag list matches the remainder of the string.
Last playedNo Search, no TrackID, SimpleSearch=0The most recently played track on the station.
Track by IDTrackID setExactly one track.
SearchSearch set (or SimpleSearch=1)Tracks whose title or artist matches, ordered by artist.
Regardless of mode, at most 50 track records are returned in one response.

Request

AttributeMandatory?DescriptionNotes
jwtYesJWT token that authenticates the call.Get from the get-token endpoint. Password is accepted as an alias.
StationIDYesThe station to read from. Defaults to 1 if omitted or invalid.1 = ericade.radio
2 = Best of ericade.radio
NowPlayingNo0 = Off (default), 1 = On. Returns the currently playing track and applies buffer compensation automatically.
TrackIDNoReturn one specific track. Numeric, up to 5 digits.15717
SearchNoFree-text search term, matched against title and artist. Prefix with Tags: to search the tag list instead.my wolf
Tags: Revision 2026
SimpleSearchNo0 = full record (default), 1 = lightweight search that skips the podcast, description and rating columns. Saves bandwidth for autocomplete-style lookups.
MaxResultsNoMaximum number of search results. 1–2 digits; defaults to 100 when omitted.20
EligibilityFilterNo0 = return all matches (default), 1 = drop tracks that cannot be requested right now.
SequenceNoBandwidth-saving mechanism. Send 0 (or omit) to always receive a full response, or send the TimeStamp value from the previous response. If the current track’s start time matches the value you sent, the API returns HTTP 204; if it differs, a full response is returned.Set to 0 on non-metered connections.
DisableBufferCompensationNo0 = use buffer compensation (default), 1 = disable. The API holds the current track for a preset number of seconds to compensate for stream buffering.Should always be 0 or omitted unless explicitly needed.
ReturnNextUpNo0 = do not return NextUp (default), 1 = return the NextUp array (up to 3 entries).
ReturnArtistDescriptionNo0 = omit artist description and rating fields (default), 1 = include them.Setting this to 0 also forces ReturnArtistLongDescription, ReturnProductionNotes and ReturnPlayList to 0.
ReturnArtistLongDescriptionNo0 = off (default), 1 = include the full artist biography.Requires ReturnArtistDescription=1.
ReturnProductionNotesNo[Podcast] 0 = off (default), 1 = include ProductionNotes.Requires ReturnArtistDescription=1.
ReturnPlayListNo[Podcast] 0 = off (default), 1 = include PlayList. Also needed for NowPlayingOnPlaylist to be populated.Requires ReturnArtistDescription=1.
LastPlaysToReturnNoNumber of Playlog entries to return. Defaults to 3, hard-capped at 15.3
ReturnShowNotesNo(No effect) Accepted and validated, but show notes are not part of the response schema.

Example request

{
  "jwt": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...",
  "StationID": 1,
  "NowPlaying": 1,
  "Sequence": 0,
  "ReturnArtistDescription": 1,
  "ReturnNextUp": 1
}
HTTP 204: Returned when the Sequence value matches the current track’s start time. The caller should display the previously received data unchanged.

Response

Returns a {"Tracks": [...]} object. The array holds one entry in now-playing and track-by-ID mode, and up to MaxResults (max 50) entries in search mode.

AttributeDescriptionExample
ArtistComplete artist field including all collaborators.Cube
TitleTrack title.My pixels are weapons
TrackUpdatedAtWhen the track’s metadata was last updated.2026-06-12 09:41:02
TrackArtistsArray of all artists linked to this track (a track can have more than one).Array[]
TrackArtists => ArtistIDUnique artist identifier.4821
TrackArtists => ArtistArtist name.Cube
TrackArtists => ShortDescriptionShort artist bio.(text)
TrackArtists => LongDescriptionFull artist bio.(text)
TrackArtists => CompositeRatingArtist rating from 0.0–5.0.4.6
TrackArtists => VotesNumber of votes the artist has received.12
TrackArtists => TotalPlaysNumber of times this artist has been played.6789
TrackArtists => DemozooLink to the artist’s profile on demozoo.org.
TrackArtists => WikipediaLink to the artist’s Wikipedia entry.
TrackArtists => CSDBLink to the artist’s C64 Scene Database profile.
TrackArtists => OtherUrlLink to the artist’s homepage or other point of interest.
TrackArtists => ModArchiveLink to the artist’s ModArchive profile.
TrackArtists => BandcampLink to the artist’s Bandcamp page.
TrackArtists => SoundCloudLink to the artist’s SoundCloud profile.
TrackArtists => YouTubeLink to the artist’s YouTube channel.
TrackArtists => PouetLink to the artist’s Pouet profile.
TrackArtists => isBroadcastProhibitedWhether broadcasting this artist’s tracks is prohibited.0 or 1
TrackArtists => isDownloadProhibitedWhether downloading this artist’s tracks is prohibited.0 or 1
StationIDStation number.1
StationNameStation name in plain text.24/7 tracked music
SlugURL-friendly slug for the track.https://ericade.radio/#/song/14820/mindstorm-trackerartist
WebStreamingOffsetWeb streaming offset for the station in seconds. Used for webplayers.12
StreamingOffsetStreaming offset for the station in seconds. Used for all other players.10
TrackCanBeRequestedWhether this track can be requested right now.0 or 1
RequestVerdictHuman-readable reason why the track cannot be requested. Echo this string to the user.Song was played recently
CreationDateHRWhen the track was first added to the station, human-readable.2026-03-30 15:45:04
CreationDateWhen the track was first added, Unix epoch string.1774885504
AddedDate(Deprecated) Same as CreationDateHR.2026-03-30 15:45:04
TrackCanBeStarredWhether this track can receive a star rating right now.0 or 1
PodcastURL[Podcast] URL to the podcast audio file.https://radio.ericade.net/Flashback/97.mp3
EpisodeNumber[Podcast] Episode number. Empty for non-podcast tracks.97
ImageImage URL for this track.https://radio.ericade.net/images/demoscene.png
BroadcastDate[Podcast] Broadcast date of the podcast episode.2022-07-16
TitleID(Deprecated) Not in use.13770
TrackIDUnique, stable track identifier. Use this in all requests that reference a specific track.15717
TrackerTypeType/format of the track.Modern remix (demo scene)
TypeStated/inferred song type from PlayIT Live. Not actively used.Song
Tags(Deprecated) Tags as a raw comma-separated string. Use TagList.“”
TagListList of tags associated with the track.[]
PlayLengthLength between Cue In and Cue Out in seconds (decimal, “.” separator).193.12099773243
PlayLengthHRPlay length expressed as MM:SS (HH:MM:SS for tracks over an hour).03:13
BatchBatch number auto-parsed from the Album field. Format: <StationShortName>-<MonMMMYYYY>-<nn>.TERN-mar2026-03
AlbumAlbum tag from the audio file’s metadata.OriginalName:!Cube - My Pixels Are Weapons.ogg Imported:2026-03-29 (TERN-mar2026-03).
AboutShort description from the song or podcast episode.
ProductionNotes[Podcast] Production notes. Only populated when ReturnProductionNotes=1.
PlayList[Podcast] Chapter list for the podcast episode. Only populated when ReturnPlayList=1.00:00 Introduction…
Transcript[Podcast] Full transcript of the episode. Empty for non-podcast tracks.
Footer[Podcast] Footer text/show notes appended to the episode. Empty for non-podcast tracks.
Equipment[Podcast] Equipment used to record the episode. Empty for non-podcast tracks.
CompositeRatingTrack rating from 0.0–5.0. Higher is better.4.3
VotesNumber of votes the track has received.2
ArtistCompositeRatingArtist rating from 0.0–5.0.4.9
ArtistVotesNumber of votes the artist has received.0
TimeStampTrack start time as Unix epoch. Required for progress bar calculations and the Sequence mechanism.1774885504
TimeStampHumanReadableTrack start time as a human-readable date string.2026-03-30 15:45:04
TrackTotalPlaysNumber of times this track has been played on the station.313
ArtistTotalPlaysNumber of times the artist has been played. Currently reflects the first artist only; will be revised.206
ArtistLongDescriptionFull biography of the first linked artist. Only populated when ReturnArtistDescription=1; prefer the per-artist text inside TrackArtists. Empty on every answer between 2026-08-14 and 2026-10-26; populated again since.(text)
ArtistShortDescription(Deprecated) Do not use.
NowPlayingOnPlaylist[Podcast] [Best of ericade.radio (StationID=2)] Returns the current chapter.
Requires ReturnPlayList=1 in the call to work.
Love connection by Lavizh
Demozoo, Wikipedia, CSDB, OtherUrl, ModArchive, Bandcamp, SoundCloud, YouTube, PouetTop-level copies of the first linked artist’s external links. Prefer the per-artist values inside TrackArtists.
ModArchiveTrueFileNameThe module’s real filename as recorded on ModArchive.org. The enrichment job matches a track by the original filename recovered from the album string, which is not always the name ModArchive files the module under — this is the name ModArchive itself reports for the matched module. Empty when the track is not a tracker module. When populated, the data enrichment will use that name instead of the one inferred from the Album column when calling ModArchive.virgill-bratgrumbeere.mod
isListenerRequested1 while the station is playing this track as a listener request, otherwise 0 — in every mode of this endpoint since 2026-10-26 (before, only NowPlaying=1 could say 1). The track record is the same object in every answer of the API: see One track object.0 or 1
isOverrideIf 0 (default), the returned data shows the currently playing track. This is the normal behaviour.
If 1, it shows a preset text from the database, used for special messages or to tell the listener which live show they are hearing.
0 or 1
isLiveOnly meaningful when isOverride is 1. Indicates that you are listening to a live show.0 or 1
isRemoteOnly meaningful when isOverride is 1. Indicates a live show broadcast from a remote location.0 or 1
isNew1 when CreationDate is within the station’s NewDays, otherwise 0. (Until 2026-10-26 every answer said 0.)0 or 1
NewDaysNumber of days a track is considered new on this station.7
PodcastPresent in all responses. Empty string for non-podcast tracks.“”
musicURLDirect URL to the track’s audio file.https://radio.ericade.net/mods/cube-my_pixels_are_weapons.ogg
musicURLFlacDirect URL to the track’s FLAC file, when available. Empty if no FLAC version exists.
musicURLOriginal(Not yet implemented) Intended to be the direct URL to the track’s original tracker file (.mod, .it, .xm and so on). The resolver behind it is a stub, so it is currently an empty string on every endpoint — as is the original entry in Media. Do not build a download option on it yet.
MediaThe three URLs above expressed as an array of {"type", "url"} objects, with types mp3, flac and original. Convenience wrapper for players that iterate over available formats. The original entry’s URL is currently always empty.Array[]
isBroadcastProhibitedWhether broadcasting this track is prohibited.0 or 1
isDownloadProhibitedWhether downloading this track is prohibited. If 1, the music URLs are empty.0 or 1
IntegrityChecksums of the track’s audio file, in lowercase hex. Always present with all four keys. Only podcast episodes are checksummed at the moment (the file is the episode MP3 at PodcastURL); for every other track, and for an episode that has not been checksummed yet, each value is an empty string. See News & Podcasts for the checksum files published next to each episode.Object{}
Integrity => md5MD5 checksum, 32 characters.ab8effe6ef0c5eb07803dd92ac14ac09
Integrity => sha1SHA-1 checksum, 40 characters.803d89f5701d0882a97e43ebfb231928e7ca4522
Integrity => sha256SHA-256 checksum, 64 characters.b886baff39c8ed3489d9275aa1cbd24af9b1a1885b02a0789d69242af7ff4176
Integrity => sha384SHA-384 checksum, 96 characters.f565bafcadb72fd55ef9948f1d63f2bf1ad060d02b40a63ca03209d125ec1abd730bedd0ee7c8947709953d029832160
PlaylogArray of recent play timestamps for this track on this station. Length controlled by LastPlaysToReturn.Array[]
Playlog => timestamphrHuman-readable datetime the track was played.2026-03-30 16:00:06
NextUpArray of the next tracks’ info (up to 3). The key is omitted entirely unless ReturnNextUp=1. Station IDs and adverts are excluded.Array[]
NextUp => ArtistArtist name of the next track.MA2E
NextUp => TitleTitle of the next track.Thrilled 4 noise
NextUp => AddedDateWhen the next track was first added, human-readable.2022-04-09 14:41:38
NextUp => CompositeRatingRating 0.0–5.0.3.5
NextUp => VotersVote count.0
NextUp => ImageImage URL.https://radio.ericade.net/images/demoscene.png
NextUp => StationIDStation the next track belongs to.1
NextUp => TrackerTypeTrack type/format.Amiga 4-channel module
NextUp => TrackIDUnique track identifier.11971

Example response

{
  "Tracks": [
    {
      "Artist": "Chris Huelsbeck",
      "Title": "Dressed to chill",
      "TrackUpdatedAt": "2026-06-12 09:41:02",
      "TrackArtists": [
        {
          "ArtistID": 4821,
          "Artist": "Chris Huelsbeck",
          "ShortDescription": "A true legend on the Amiga and other systems.",
          "LongDescription": "A true legend on the Amiga and other systems. He's most famous for the music from Turrican I, II and III.",
          "CompositeRating": 4.6,
          "Votes": 12,
          "TotalPlays": 6789,
          "Demozoo": "https://demozoo.org/sceners/7637/",
          "Wikipedia": "",
          "CSDB": "",
          "OtherUrl": "",
          "ModArchive": "",
          "Bandcamp": "https://chrishuelsbeck.bandcamp.com/",
          "SoundCloud": "",
          "YouTube": "",
          "Pouet": "",
          "isBroadcastProhibited": 0,
          "isDownloadProhibited": 0
        }
      ],
      "StationID": 1,
      "StationName": "24/7 tracked music",
      "Slug": "https://radio.ericade.net/#/song/14051/dressed to chill-chris-huelsbeck",
      "WebStreamingOffset": 12,
      "StreamingOffset": 10,
      "TrackCanBeRequested": 0,
      "RequestVerdict": "Artist was played recently",
      "CreationDateHR": "2022-11-01 16:19:08",
      "CreationDate": "1667315948",
      "AddedDate": "2022-11-01 16:19:08",
      "TrackCanBeStarred": 1,
      "PodcastURL": "",
      "EpisodeNumber": "",
      "Image": "https://radio.ericade.net/images/rmx.png",
      "BroadcastDate": "",
      "TitleID": 12098,
      "TrackID": 14051,
      "TrackerType": "Modern remix",
      "Type": "Song",
      "Tags": "",
      "TagList": [],
      "PlayLength": 273.39934240363,
      "PlayLengthHR": "04:33",
      "Batch": "TERN-oct2022-05",
      "Album": "OriginalName:custom.rmx Imported:2022-11-01 (TERN-oct2022-05).",
      "About": "",
      "ProductionNotes": "",
      "PlayList": "",
      "Transcript": "",
      "Footer": "",
      "Equipment": "",
      "CompositeRating": 0,
      "Votes": 0,
      "ArtistCompositeRating": 4.6,
      "ArtistVotes": 12,
      "TimeStamp": 1778939868,
      "TimeStampHumanReadable": "2026-05-16 13:57:48",
      "TrackTotalPlays": 216,
      "ArtistLongDescription": "A true legend on the Amiga and other systems.",
      "ArtistShortDescription": "A true legend on the Amiga and other systems.",
      "NowPlayingOnPlaylist": "",
      "Demozoo": "https://demozoo.org/sceners/7637/",
      "Wikipedia": "",
      "CSDB": "",
      "OtherUrl": "",
      "ModArchive": "",
      "Bandcamp": "https://chrishuelsbeck.bandcamp.com/",
      "SoundCloud": "",
      "YouTube": "",
      "Pouet": "",
      "ModArchiveTrueFileName": "virgill-bratgrumbeere.mod",
      "isListenerRequested": 0,
      "isOverride": 0,
      "isLive": 0,
      "isRemote": 0,
      "isNew": 0,
      "NewDays": 7,
      "Podcast": "",
      "musicURL": "https://radio.ericade.net/mods/custom.rmx",
      "musicURLFlac": "",
      "musicURLOriginal": "",
      "Media": [
        { "type": "mp3", "url": "https://radio.ericade.net/mods/custom.rmx" },
        { "type": "flac", "url": "" },
        { "type": "original", "url": "" }
      ],
      "isBroadcastProhibited": 0,
      "isDownloadProhibited": 0,
      "Integrity": {
        "md5": "",
        "sha1": "",
        "sha256": "",
        "sha384": ""
      },
      "ArtistTotalPlays": 6789,
      "Playlog": [
        { "timestamphr": "2026-05-16 13:57:48" },
        { "timestamphr": "2026-05-07 22:38:33" },
        { "timestamphr": "2026-04-28 16:05:51" }
      ],
      "NextUp": [
        {
          "Artist": "SoundLogic",
          "Title": "Monty on the run",
          "AddedDate": "2024-09-15 14:12:50",
          "CompositeRating": "5.0",
          "Voters": "1",
          "Image": "https://radio.ericade.net/images/demoscene.png",
          "StationID": "1",
          "TrackerType": "Modern remix (demo scene)",
          "TrackID": "14925"
        }
      ]
    }
  ]
}

Track by ID

Returns full metadata for one specific track, addressed through the URL rather than through a body field. The response schema is identical to Get Track.

POST https://api.ericade.net/radio/songs/<trackid>/

Replace <trackid> with the numeric TrackID. The path segment is passed straight through to the TrackID field, so any value you put in the body is ignored.

Request

Accepts the same fields as Get Track, with two differences:

Example request

{
  "Token": "eyJ0eXAiOiJKV1Qi...",
  "StationID": 1,
  "ReturnArtistDescription": 1
}
Calling /radio/songs/ with an empty path does not return a track — it falls through to the List Tracks behaviour instead, using the same body fields as that endpoint.

List Tracks

Dumps the station’s track library with pagination and a total count. Intended for report and browse views rather than for players. This endpoint only ever queries the titles table (no joins), so every field the Get Track response has that is sourced from that table is present here too, under the same name. What is missing is exactly what a join or a separate table would be needed for: TrackArtists, NextUp, per-artist rating/bio/external-link fields, Playlog, TimeStamp/TimeStampHumanReadable, isListenerRequested, isOverride and ArtistTotalPlays. Use Get Track when you need those.

POST https://api.ericade.net/radio/listtracks/

Request

AttributeMandatory?DescriptionNotes
jwtYesJWT token that authenticates the call.Get from the get-token endpoint.
StationIDYesThe station to list tracks from.1 = ericade.radio
2 = Best of ericade.radio
CountNoNumber of tracks to return. Defaults to 10; values outside 0–9000 are rejected.50
SkipNoNumber of tracks to skip from the start (for pagination). Defaults to 0; values outside 0–10000 are rejected.0
SearchNoFree-text term matched against artist and title. Prefix with Tag: to search the tag list instead. Max 30 characters. When omitted, station-ID jingles (artist ericade.radio) are excluded.virgill
Tag:Revision
CGuidNo(No effect) Accepted but unused.
Results are ordered by artist then title. On StationID 2 they are ordered by creation date descending instead.

Example request

{
  "jwt": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...",
  "StationID": 1,
  "Skip": 0,
  "Count": 25,
  "Search": "virgill"
}

Response

Returns a Query array with the paging counters, followed by the Tracks array.

AttributeDescriptionExample
Query => ResultCountNumber of tracks in this response.25
Query => TotalCountTotal number of tracks matching the query, ignoring Skip/Count.312
Tracks => ID, TrackID, TitleIDUnique track identifier. All three are the same value — ID is this endpoint’s original key, TrackID/TitleID are added for parity with Get Track.10147
Tracks => StationIDThe station this track belongs to.1
Tracks => StationNameHuman-readable station name.24/7 tracked music
Tracks => WebStreamingOffsetWeb streaming offset for the station in seconds.12
Tracks => StreamingOffsetStreaming offset for the station in seconds.10
Tracks => TitleTrack title.Bratgrumbeere
Tracks => Fullartist, ArtistComplete artist field including all collaborators. Both keys carry the same value; Fullartist is this endpoint’s original key, Artist matches Get Track.Virgill
Tracks => SlugURL-friendly slug for the track.https://ericade.radio/song/10147/bratgrumbeere-virgill
Tracks => TrackUpdatedAtWhen the track’s metadata was last updated.2026-06-12 09:41:02
Tracks => AlbumAlbum tag from the audio file’s metadata.Original Amiga Works (.mod) TERN-Okt2020-S1
Tracks => ImageImage URL derived from the album/format.https://radio.ericade.net/images/mod.png
Tracks => Creationdatehr, CreationDateHR, AddedDateWhen the track was first added, human-readable. All three carry the same value; Creationdatehr is this endpoint’s original key, the other two match Get Track (AddedDate is deprecated there too).2022-11-01 16:19:08
Tracks => CreationDateWhen the track was first added, Unix epoch string.1667315948
Tracks => TrackCanBeStarredWhether this track can receive a star rating right now.0 or 1
Tracks => Length, PlayLengthLength between Cue In and Cue Out, in seconds. Same value under both keys; Length is a string (this endpoint’s original key), PlayLength is a number matching Get Track.292.757
Tracks => Lengthhr, PlayLengthHRLength expressed as MM:SS.04:52
Tracks => BatchBatch number auto-parsed from the Album field.TERN-Okt2020-S1
Tracks => Tracktype, TrackerTypeType/format of the track. Same value under both keys; Tracktype is this endpoint’s original key, TrackerType matches Get Track.Amiga 4-channel module
Tracks => TypeStated/inferred song type from PlayIT Live. Not actively used.Song
Tracks => isPodcastWhether this is a podcast episode rather than a music track.0 or 1
Tracks => PodcastPresent in all responses. Empty string for non-podcast tracks.“”
Tracks => PodcastURL[Podcast] URL to the podcast audio file.
Tracks => EpisodeNumber[Podcast] Episode number. Empty for non-podcast tracks.
Tracks => BroadcastDate[Podcast] Broadcast date of the podcast episode.
Tracks => AboutShort description from the song or podcast episode.
Tracks => ProductionNotes[Podcast] Production notes. Empty for non-podcast tracks.
Tracks => PlayList[Podcast] Chapter list for the podcast episode. Empty for non-podcast tracks.
Tracks => Transcript[Podcast] Full transcript of the episode. Empty for non-podcast tracks.
Tracks => Footer[Podcast] Footer text/show notes appended to the episode. Empty for non-podcast tracks.
Tracks => Equipment[Podcast] Equipment used to record the episode. Empty for non-podcast tracks.
Tracks => CompositeRatingTrack rating from 0.0–5.0. Higher is better.4.3
Tracks => VotesNumber of votes the track has received.2
Tracks => TrackTotalPlaysNumber of times this track has been played on the station.313
Tracks => NowPlayingOnPlaylist[Podcast] Chapter that would be current right now, computed the same way as on Get Track.
Tracks => TrackCanBeRequestedWhether this track can be requested right now. Computed the same way as Get Track, except it does not check the next-up queue (that needs the nextup table), so a track that is next in queue is not flagged ineligible for that reason here.0 or 1
Tracks => RequestVerdictHuman-readable reason from the eligibility check above.Song was played recently
Tracks => isLiveWhether the Album field marks this as a live recording.0 or 1
Tracks => isRemoteWhether the Type field marks this as a remote broadcast.0 or 1
Tracks => isNewWhether the track was added within the station’s new-track window.0 or 1
Tracks => NewDaysNumber of days a track is considered new on this station.7
Tracks => isBroadcastProhibitedWhether broadcasting this track is prohibited.0 or 1
Tracks => isDownloadProhibitedWhether downloading this track is prohibited. If 1, the music URLs and every Media entry are empty.0 or 1
Tracks => musicURLDirect URL to the track’s audio file.https://radio.ericade.net/mods/custom.mod
Tracks => musicURLFlacDirect URL to the track’s FLAC audio file, when available. Empty if no FLAC version exists.
Tracks => musicURLOriginal(Not yet implemented) Always an empty string — see the note on this field in the Get Track table.
Tracks => MediaThe three URLs above expressed as a typed list, in the fixed order mp3, flac, original.Array[]
Tracks => IntegrityChecksums of the track’s audio file: md5, sha1, sha256 and sha384. Same object as Integrity in the Get Track response — see that table. Each value is an empty string for a track that has not been checksummed.Object{}
Tracks => PathInternal playout path of the file.
Tracks => GuidInternal GUID from PlayIT Live. Not intended for public use.6894ac27-abc9-4c4a-aad2-15879dda4dff
Tracks => TagsComma-separated tag list.Revision, Revision 2026
Tracks => TagListList of tags associated with the track.[]
Tracks => MA_NextUpdate(Kept for backward compatibility) Same value as ModArchiveEnrichment => MA_NextUpdate below.
Tracks => ModArchiveTrueFileNameThe module’s real filename as recorded on ModArchive.org. See the Get Track table for the full description.virgill-bratgrumbeere.mod
Tracks => ModArchiveEnrichmentModule metadata from ModArchive.org, read directly off this row. Same 22 MA_* fields as v2’s Now Playing response (this endpoint has no v1 sibling with the full field list documented).Array[]
Fields not listed here (TrackArtists, NextUp, per-artist rating/bio/external-link fields, Playlog, TimeStamp, TimeStampHumanReadable, isListenerRequested, isOverride, ArtistTotalPlays) are not present on this endpoint — they need a join or a separate table, and this endpoint only ever queries titles. Use Get Track for those.
When nothing matches, the response is { "Software":["No track information was found."]} with HTTP 200 — there is no Tracks key at all. Handle that shape explicitly.

Example response

{
  "Query": [
    {
      "ResultCount": "1",
      "TotalCount": "312"
    }
  ],
  "Tracks": [
    {
      "ID": 10147,
      "TrackID": 10147,
      "TitleID": 10147,
      "StationID": 1,
      "StationName": "24/7 tracked music",
      "WebStreamingOffset": 12,
      "StreamingOffset": 10,
      "Title": "Bratgrumbeere",
      "Fullartist": "Virgill",
      "Artist": "Virgill",
      "Slug": "https://ericade.radio/song/10147/bratgrumbeere-virgill",
      "TrackUpdatedAt": "2026-06-12 09:41:02",
      "Album": "Original Amiga Works (.mod) TERN-Okt2020-S1",
      "Image": "https://radio.ericade.net/images/mod.png",
      "Creationdatehr": "2020-10-14 12:02:11",
      "CreationDateHR": "2020-10-14 12:02:11",
      "CreationDate": "1602676931",
      "AddedDate": "2020-10-14 12:02:11",
      "TrackCanBeStarred": 1,
      "Length": "292.757",
      "Lengthhr": "04:52",
      "PlayLength": 292.757,
      "PlayLengthHR": "04:52",
      "Batch": "TERN-Okt2020-S1",
      "Tracktype": "Amiga 4-channel module",
      "TrackerType": "Amiga 4-channel module",
      "Type": "Song",
      "isPodcast": 0,
      "Podcast": "",
      "PodcastURL": "",
      "EpisodeNumber": "",
      "BroadcastDate": "",
      "About": "",
      "ProductionNotes": "",
      "PlayList": "",
      "Transcript": "",
      "Footer": "",
      "Equipment": "",
      "CompositeRating": 0,
      "Votes": 0,
      "TrackTotalPlays": 313,
      "NowPlayingOnPlaylist": "",
      "TrackCanBeRequested": 1,
      "RequestVerdict": "Song can be requested",
      "isLive": 0,
      "isRemote": 0,
      "isNew": 0,
      "NewDays": 7,
      "isBroadcastProhibited": 0,
      "isDownloadProhibited": 0,
      "musicURL": "https://radio.ericade.net/mods/virgill-bratgrumbeere.mod",
      "musicURLFlac": "",
      "musicURLOriginal": "",
      "Media": [
        { "type": "mp3", "url": "https://radio.ericade.net/mods/virgill-bratgrumbeere.mod" },
        { "type": "flac", "url": "" },
        { "type": "original", "url": "" }
      ],
      "Integrity": {
        "md5": "",
        "sha1": "",
        "sha256": "",
        "sha384": ""
      },
      "Path": "\\mods\\virgill-bratgrumbeere.mod",
      "Guid": "aace857b-366a-46fe-9208-1d5b9fc0caae",
      "Tags": "",
      "TagList": [],
      "MA_NextUpdate": "",
      "ModArchiveTrueFileName": "virgill-bratgrumbeere.mod",
      "ModArchiveEnrichment": [
        {
          "MA_Format": "",
          "MA_URL": "",
          "MA_Date": "",
          "MA_Hash": "",
          "MA_Size": "",
          "MA_SongTitle": "",
          "MA_Instruments": "",
          "MA_GenreID": 0,
          "MA_Rating": 0,
          "MA_Comments": "",
          "MA_ReviewRating": 0,
          "MA_ReviewTotal": 0,
          "MA_ImageUrl": "",
          "MA_Artists": "",
          "MA_GuessedArtists": "",
          "MA_LastUpdated": 0,
          "MA_HasFile": 0,
          "MA_Bytes": 0,
          "MA_TimeStamp": 0,
          "MA_Found": 0,
          "MA_LastSync": "",
          "MA_NextUpdate": ""
        }
      ]
    }
  ]
}

News & Podcasts

Lists news posts and podcast episodes, with pagination, tag search and optional transcripts. This is the endpoint that backs the podcast display pages and the RSS feed builder.

POST https://api.ericade.net/radio/listnews/

Request

AttributeMandatory?DescriptionNotes
jwtYesJWT token that authenticates the call.Get from the get-token endpoint.
StationIDYesThe station to read from.1 = ericade.radio
2 = Best of ericade.radio
PodcastsNo0 = do not filter on podcasts (default), 1 = only podcast entries, 2 = podcast entries including the track length columns.
NewsNo0 = off (default), 1 = include news entries. Combine with Podcasts to get both.
IDNoReturn only the entry linked to this TrackID. Also switches on the length columns.13770
CountNoNumber of entries to return. Defaults to 200; values outside 0–200 are rejected.20
SkipNoNumber of entries to skip from the start (for pagination). Values outside 0–300 are rejected.0
SearchNoFree-text term matched against artist and title. Prefix with Tag: to search the tag list instead. Max 30 characters.Tag:Revision 2026
IncludeTagsNo0 = off (default), 1 = join in the tag column so Tags/TagList are populated.
ReturnTranscriptsNo0 = return an empty Transcript (default), 1 = return the full transcript text. Transcripts are large — leave this off unless you display them.
Results are ordered by broadcast date descending, then episode number descending, then timestamp descending, then title.

Example request

{
  "jwt": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...",
  "StationID": 2,
  "Podcasts": 2,
  "Count": 10,
  "Skip": 0,
  "IncludeTags": 1,
  "ReturnTranscripts": 0
}

Response

Returns a Query array with the paging counters, followed by the Tracks array.

AttributeDescriptionExample
Query => ResultCountNumber of entries in this response.10
Query => TotalCountTotal number of entries matching the query.97
TrackIDUnique identifier of the track the post is linked to.13770
TitleEpisode or post title.Flashback episode 97
ArtistShow or author name.ericade.radio
TrackUpdatedAtWhen the entry was last updated.2026-06-12 09:41:02
AboutShort description of the episode or post.
ModArchiveTrueFileNameThe module’s real filename as recorded on ModArchive.org — see the Get Track table. Always empty for news posts, which are stored in a table that has no such column, and empty for podcast episodes, which are not tracker modules.
SlugURL-friendly slug for the entry.https://radio.ericade.net/#/song/13770/flashback-97
Episode[Podcast] Episode number as a string. Empty for non-podcast entries.97
ExplicitExplicit-content flag for the podcast feed.0 or 1
LastBuildTimestamp of the last RSS feed build. Only present when the stats row exists.2026-08-01 04:00:02
LengthTrack length in seconds. Only present when Podcasts=2 or ID is set.3612.4
LengthHRTrack length as MM:SS (HH:MM:SS when over an hour). Same condition as Length.01:00:12
BroadcastDate[Podcast] Broadcast date of the episode.2022-07-16
ImageImage URL for the entry.https://radio.ericade.net/wp-content/uploads/2020/12/amiga_flashback.jpg
PodcastImage[Podcast] Dedicated podcast artwork URL, when set.
CompositeRatingRating from 0.0–5.0.4.3
TrackVotesNumber of votes the entry has received.2
TagsComma-separated tag list. Empty unless IncludeTags=1 or a tag search was performed.Revision, Revision 2026
TagListThe same tags as an array.[]
Equipment[Podcast] Equipment used to record the episode.
PlayList[Podcast] Chapter list for the episode.00:00 Introduction…
ProductionNotes[Podcast] Production notes.
hasTranscript1 when a transcript exists for this entry, 0 otherwise. Use it to decide whether a second call with ReturnTranscripts=1 is worth making.0 or 1
TranscriptFull transcript text. Empty unless ReturnTranscripts=1.
ShowNotes[Podcast] Show notes for the episode.
Footer[Podcast] Footer text appended to the episode.
isNews1 when the entry is a news post.0 or 1
isPodcast1 when the entry is a podcast episode.0 or 1
isRSS1 when the entry is published in the RSS feed.0 or 1
NewsBody text of the news post.
PodcastFileLength[Podcast] Size of the audio file in bytes, for the RSS enclosure.57829120
PodcastURL[Podcast] URL to the podcast audio file.https://radio.ericade.net/Flashback/97.mp3
Integrity[Podcast] Checksums of the MP3 at PodcastURL: md5, sha1, sha256 and sha384. Same object as Integrity in the Get Track response. Each value is an empty string for news posts, and for an episode that has not been checksummed yet.Object{}
EpisodeNumber[Podcast] Episode number as a number. 0 for non-podcast entries.97
The md5, sha256 and sha384 checksums are also published as files next to each episode’s MP3. For https://radio.ericade.net/Flashback/97.mp3 they are 97.md5, 97.sha256 and 97.sha384 in the same directory. Each file holds one line in the format md5sum -c, sha256sum -c and sha384sum -c read, so a downloaded episode can be checked by running, for example, sha256sum -c 97.sha256 in the directory it was saved to.
When nothing matches, the response is { "Tracks":["No news information was found."]} — an array of strings rather than of objects. Handle that shape explicitly.

Example response

{
  "Query": [
    {
      "ResultCount": "1",
      "TotalCount": "97"
    }
  ],
  "Tracks": [
    {
      "TrackID": "13770",
      "Title": "Flashback episode 97",
      "Artist": "ericade.radio",
      "TrackUpdatedAt": "2026-06-12 09:41:02",
      "About": "A trip back to the Amiga demo scene of 1992.",
      "ModArchiveTrueFileName": "",
      "Slug": "https://radio.ericade.net/#/song/13770/flashback-episode-97-ericade-radio",
      "Episode": "97",
      "Explicit": "0",
      "LastBuild": "2026-08-01 04:00:02",
      "Length": "3612.4",
      "LengthHR": "01:00:12",
      "BroadcastDate": "2022-07-16",
      "Image": "https://radio.ericade.net/wp-content/uploads/2020/12/amiga_flashback.jpg",
      "PodcastImage": "",
      "CompositeRating": "4.3",
      "TrackVotes": "12",
      "Tags": "Amiga, Flashback",
      "TagList": ["Amiga", "Flashback"],
      "Equipment": "",
      "PlayList": "00:00 Introduction...",
      "ProductionNotes": "",
      "hasTranscript": "1",
      "Transcript": "",
      "ShowNotes": "",
      "Footer": "",
      "isNews": "0",
      "isPodcast": "1",
      "isRSS": "1",
      "News": "",
      "PodcastFileLength": "57829120",
      "PodcastURL": "https://radio.ericade.net/Flashback/97.mp3",
      "Integrity": {
        "md5": "ab8effe6ef0c5eb07803dd92ac14ac09",
        "sha1": "803d89f5701d0882a97e43ebfb231928e7ca4522",
        "sha256": "b886baff39c8ed3489d9275aa1cbd24af9b1a1885b02a0789d69242af7ff4176",
        "sha384": "f565bafcadb72fd55ef9948f1d63f2bf1ad060d02b40a63ca03209d125ec1abd730bedd0ee7c8947709953d029832160"
      },
      "EpisodeNumber": 97
    }
  ]
}

Add News

Creates a news post or podcast episode and uploads its artwork. The submitted PNG is stored and then automatically rescaled into the twelve sizes the website and podcast feed use.

POST https://api.ericade.net/radio/addnews/
Editorial endpoint. It writes to the content database and to the web server’s upload directory, and is not intended for third-party use.

Request

AttributeMandatory?DescriptionNotes
jwtYesJWT token that authenticates the call.Get from the get-token endpoint.
TitleYesEpisode or post title. Max 255 characters.Flashback episode 97
ArtistNoShow or author name. Max 255 characters.ericade.radio
IsPodcastYes*Set to 1 for a podcast episode.Exactly one of IsPodcast / IsNews must be 1. Setting both is rejected.
IsNewsYes*Set to 1 for a news post.See above.
BroadcastDateYesBroadcast/publication date. Max 15 characters. Required for both post types.2022-07-16
EpisodeNumberYes (podcast)Episode number. Used to derive the audio file URL and its size on disk.97
NewsNoBody text of the news post. Max 4096 characters.
EquipmentNoEquipment used to record the episode. Max 4096 characters.
PlayListNoChapter list for the episode. Max 4096 characters.
ProductionNotesNoProduction notes. Max 4096 characters.
FilenameYesBase name for the artwork, max 220 characters. Only one dot is permitted — more than one is rejected.flashback-97.png
FileDataYesBase64-encoded PNG image, max 16 MB decoded.iVBORw0KGgoAAAANSUhEUg…
The uploaded PNG is saved under the current year/month upload folder and rescaled into: 100x44, 150x150, 170x17, 200x110, 300x300, 690x302, 690x690, 768x768, 1024x1024, 1170x512 and 1400x700.

Example request

{
  "jwt": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...",
  "IsPodcast": 1,
  "IsNews": 0,
  "Artist": "ericade.radio",
  "Title": "Flashback episode 97",
  "EpisodeNumber": 97,
  "BroadcastDate": "2022-07-16",
  "Filename": "flashback-97.png",
  "FileData": "iVBORw0KGgoAAAANSUhEUg..."
}

Response

The standard envelope. On success subcode is Done. and submessage is All done.

Playout History

Returns the most recently played tracks on a station, or — in last-added mode — the most recently imported tracks with their request eligibility. This is the v1 equivalent of Song History.

POST https://api.ericade.net/radio/getplayout/

Request

AttributeMandatory?DescriptionNotes
PasswordYesJWT token that authenticates the call.Get from the get-token endpoint. jwt is accepted as an alias.
StationIDYesThe station to get history for.1 = ericade.radio
2 = Best of ericade.radio
NumberOfTracksNoNumber of entries to return. Defaults to 10; more than 100 is rejected.20
LastAddedModeNo0 = recently played, newest first (default).
1 = recently added to the library, newest first, with the extra rating and eligibility fields.

Example request

{
  "Password": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...",
  "StationID": 1,
  "NumberOfTracks": 10,
  "LastAddedMode": 1
}
Use LastAddedMode=1. In the default mode the underlying query does not select the creation-date columns, and the endpoint emits "CreationDate": with no value — strict JSON parsers reject the body. Until that is fixed, prefer last-added mode or use v2 Song History for play history.

Response

Returns a {"Tracks": [...]} object.

AttributeDescriptionExample
TimeStampHRWhen the track played (or was added), human-readable.2026-03-30 20:44:32
TimeStampThe same moment as a Unix epoch.1774903472
ArtistComplete artist field.Virgill
TitleTrack title.Bratgrumbeere
TrackArtistsArray of all artists linked to this track. Same object structure as TrackArtists in Get Track.Array[]
PlayLengthHR[LastAddedMode=1] Play length as MM:SS.04:52
PlayLength[LastAddedMode=1] Duration in seconds.292.757
TrackerType[LastAddedMode=1] Type/format of the track.Amiga 4-channel module
CompositeRating[LastAddedMode=1] Track rating from 0.0–5.0.4.3
Votes[LastAddedMode=1] Number of votes the track has received.2
TrackTotalPlays[LastAddedMode=1] Number of times this track has been played.313
TrackCanBeRequested[LastAddedMode=1] Whether the track can be requested right now.0 or 1
RequestVerdict[LastAddedMode=1] Human-readable reason why it cannot be requested.Song was played recently
TrackIDUnique, stable track identifier.10147
CreationDate[LastAddedMode=1] When the track was first added, Unix epoch.1667315948
CreationDateHR[LastAddedMode=1] The same moment, human-readable.2022-11-01 16:19:08
Album[LastAddedMode=1] Album tag from the audio file’s metadata.Original Amiga Works (.mod) TERN-Okt2020-S1
ImageURL to the track’s image.https://radio.ericade.net/images/mod.png
musicURLDirect URL to the track’s audio file.https://radio.ericade.net/mods/custom.mod
StationIDThe station this track belongs to.1
GuidInternal GUID from PlayIT Live. Not intended for public use.6894ac27-abc9-4c4a-aad2-15879dda4dff

Example response

{
  "Tracks": [
    {
      "TimeStampHR": "2026-05-31 21:16:42",
      "TimeStamp": 1780262202,
      "Artist": "Dr. Awesome",
      "Title": "Gone For Good",
      "TrackArtists": [
        {
          "ArtistID": 5133,
          "Artist": "Dr. Awesome",
          "ShortDescription": "",
          "LongDescription": "",
          "CompositeRating": 4.2,
          "Votes": 8,
          "TotalPlays": 412,
          "Demozoo": "",
          "Wikipedia": "",
          "CSDB": "",
          "OtherUrl": "",
          "ModArchive": "",
          "Bandcamp": "",
          "SoundCloud": "",
          "YouTube": "",
          "Pouet": "",
          "isBroadcastProhibited": 0,
          "isDownloadProhibited": 0
        }
      ],
      "PlayLengthHR": "04:52",
      "PlayLength": 292.757,
      "TrackerType": "Amiga 4-channel module",
      "CompositeRating": 4.2,
      "Votes": 8,
      "TrackTotalPlays": 313,
      "TrackCanBeRequested": 1,
      "RequestVerdict": "Track can be requested",
      "TrackID": 10147,
      "CreationDate": 1667315948,
      "CreationDateHR": "2022-11-01 16:19:08",
      "Album": "Original Amiga Works (.mod) TERN-Okt2020-S1",
      "Image": "https://radio.ericade.net/images/mod.png",
      "musicURL": "https://radio.ericade.net/mods/dr_awesome-gone_for_good.mod",
      "StationID": 1,
      "Guid": "aace857b-366a-46fe-9208-1d5b9fc0caae"
    }
  ]
}

Station Statistics

Returns the full statistics bundle for every station in one response: library breakdown, most-requested tracks, best and worst rated tracks and artists, listener geography, user agents, logoff tracks and duplicates.

POST https://api.ericade.net/radio/getstationstats/

Request

AttributeMandatory?DescriptionNotes
PasswordYesJWT token that authenticates the call.Get from the get-token endpoint. jwt is accepted as an alias.
StationIDNo(Not implemented) Accepted, but the response always covers every station.
v1 has no equivalent of the v2 Limit, Days or filter-type parameters. Every section is always returned, top/bottom lists are fixed at 10 entries and the rating and request windows are fixed at 30 days. Use v2 Statistics if you need to tune those.

Example request

{
  "Password": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9..."
}

Response

Returns a {"Stations": [...]} array. Each element represents one station.

AttributeDescriptionExample
StationIDThe station identifier.1
StationNameHuman-readable station name.24/7 tracked music
TotalLengthTotal combined length of all tracks on the station, in hours.180.4
TracksOnStationTotal number of tracks on the station.3125
TrackerstatsArray of tracker-type breakdowns, ordered by play count. Each object contains TrackerType, Tracks, Percent and StationID.Array[]
RequestsArray of the 10 most-requested tracks in the last 30 days. Each object is a full track record plus a Count field.Array[]
TopTracksArray of the 10 highest-rated tracks. Each object is a full track record.Array[]
BottomTracksArray of the 10 lowest-rated tracks (unrated tracks excluded). Same structure as TopTracks.Array[]
TopArtistsArray of the 10 highest-rated artists. Each object contains Artist, CompositeRating and Voters.Array[]
BottomArtistsArray of the 10 lowest-rated artists. Same fields as TopArtists.Array[]
StreamingCountriesArray of listener countries ordered by session count. Each object contains Country and Count.Array[]
StreamingAgentsArray of user-agent strings seen in streaming sessions. Each object contains Agent and Count.Array[]
LogoffPlayArray of up to 20 tracks most commonly playing when listeners disconnect. Each object contains Track (formatted “Artist-Title.”), NumberOfPlays and StationID.Array[]
DuplicatesArray of tracks that appear more than once in the library (same artist and title, different IDs). Each object contains FullArtist, Title and TrackID.Array[]
Entries in Requests, TopTracks and BottomTracks are full track records — see the Get Track response for the field list. They are abbreviated in the example below for readability.

Example response

{
  "Stations": [
    {
      "StationID": 1,
      "StationName": "24/7 tracked music",
      "TotalLength": 180.4,
      "TracksOnStation": 3125,
      "Trackerstats": [
        { "TrackerType": "Amiga 4-channel module", "Tracks": 1180, "Percent": 37.8, "StationID": 1 },
        { "TrackerType": "Fasttracker", "Tracks": 873, "Percent": 27.9, "StationID": 1 },
        { "TrackerType": "Impulsetracker", "Tracks": 539, "Percent": 17.2, "StationID": 1 }
      ],
      "Requests": [
        { "Artist": "Ekorren", "Title": "Little Danyjel", "TrackID": "14050", "Count": 20 },
        { "Artist": "Maf", "Title": "Mafland remix", "TrackID": "14907", "Count": 16 }
      ],
      "TopTracks": [
        { "Artist": "Xyce", "Title": "Rymdkraft - Dolph's aerobics (remix)", "CompositeRating": "5.0" }
      ],
      "BottomTracks": [
        { "Artist": "Unknown", "Title": "Untitled", "CompositeRating": "1.0" }
      ],
      "TopArtists": [
        { "Artist": "Chris Huelsbeck", "CompositeRating": "4.6", "Voters": "12" }
      ],
      "BottomArtists": [
        { "Artist": "Unknown", "CompositeRating": "1.5", "Voters": "2" }
      ],
      "StreamingCountries": [
        { "Country": "Sweden", "Count": "1204" },
        { "Country": "Germany", "Count": "883" }
      ],
      "StreamingAgents": [
        { "Agent": "VLC/3.0.20 LibVLC/3.0.20", "Count": "412" }
      ],
      "LogoffPlay": [
        { "Track": "Virgill-Bratgrumbeere.", "NumberOfPlays": "17", "StationID": "1" }
      ],
      "Duplicates": [
        { "FullArtist": "Maf", "Title": "Mafland remix", "TrackID": "14907" }
      ]
    }
  ]
}

Request Statistics

Returns the current request queue status and the most recent request history. Useful for displaying a live request line on a website.

POST https://api.ericade.net/radio/getrequeststats/

Request

AttributeMandatory?DescriptionNotes
PasswordYesJWT token that authenticates the call.Get from the get-token endpoint.
StationIDYesThe station to get request data from. The station must have requests enabled, otherwise the call fails with “This station does not allow requests.”1 = ericade.radio
2 = Best of ericade.radio

Example request

{
  "Password": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...",
  "StationID": 1
}

Response

AttributeDescriptionExample
RequestStatisticsArray containing one object with queue wait-time statistics.Array[]
RequestStatistics => TracksInQueueNumber of tracks currently waiting in the request queue.3
RequestStatistics => YourQueueNumberPosition a new request would occupy in the queue.4
RequestStatistics => ExpectedWaitingTimeInMinutesEstimated wait in minutes until a new request would be played.48
RequestStatistics => ExpectedWaitingTimeEstimated wait as a human-readable string, suitable for display. When the queue is above the station’s maximum this becomes an explanatory sentence instead of a duration.48 minutes
CurrentRequestsArray of up to five recent requests: everything still queued, topped up with the most recently played ones.Array[]
CurrentRequests => SongRequested track expressed as “<artist> - <title>”.Tommy Fjelldal - Edificated dreams
CurrentRequests => RequestedTime the request was submitted, as a Unix epoch string.1774902144
CurrentRequests => TrackIDUnique track identifier string.15715
CurrentRequests => SourceOrigin of the request.Internet or Discord
CurrentRequests => StateWhether the request is still waiting or has already been played.Waiting or Played

Example response

{
  "RequestStatistics": [
    {
      "TracksInQueue": "3",
      "YourQueueNumber": "4",
      "ExpectedWaitingTimeInMinutes": "48",
      "ExpectedWaitingTime": "48 minutes"
    }
  ],
  "CurrentRequests": [
    {
      "Song": "Tommy Fjelldal - Edificated dreams",
      "Requested": "1774902144",
      "TrackID": "15715",
      "Source": "Internet",
      "State": "Waiting"
    },
    {
      "Song": "Alexander Brandon - Frolick lane",
      "Requested": "1774902091",
      "TrackID": "15714",
      "Source": "Internet",
      "State": "Played"
    }
  ]
}

Add Request

Submits a listener request to the station’s request queue. This endpoint was never ported to v2 — the v2 documentation points back to this same URL.

POST https://api.ericade.net/radio/addrequest/
This endpoint uses Password instead of Token as the field name for the JWT value (legacy naming).

Request

AttributeMandatory?DescriptionNotes
PasswordYesJWT token that authenticates the call.Get from the get-token endpoint. Note: the field is named Password, not Token.
StationIDYesThe station to submit the request to.1 = ericade.radio
2 = Best of ericade.radio
TrackIDYesUnique identifier of the track to request. Obtain from Get Track or List Tracks.10663
SourceYesOrigin of the request. Can control which jingle plays before the track. Max 20 characters.Internet or Discord
RequesterNoThe self-selected display name of the requester. Max 120 characters.Caller #9
GreetingNo(Deprecated) A user-selectable greeting to the show host. Max 250 characters.Hi! Love your music!

Limits

The request is rejected, with an explanatory submessage, when any of the following applies:

Example request

{
  "Password": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...",
  "StationID": 1,
  "Requester": "Listener",
  "Source": "Internet",
  "TrackID": 10663
}

Response

AttributeDescriptionExample
messageIndicates whether the request was accepted. Either Success or Failure.Success
subcodeMachine-facing debug message describing what the API did internally.Added Dr Future - Plastic pop (Plastic kills life mix) to the request log
submessageHuman-facing message suitable for display to the end user.Success! The tune you requested has been added to the playlist. Expected waiting time until play: 48 minutes.

Example response

{
  "message": "Success",
  "subcode": "Added Dr Future - Plastic pop (Plastic kills life mix) to the request log",
  "submessage": "Success! The tune you requested has been added to the playlist. Expected waiting time until play: 48 minutes."
}

Star Rating

Records a listener’s 1–5 star rating for a track, then recalculates the track’s composite rating and that of every artist credited with it.

POST https://api.ericade.net/radio/updatestar/

Request

AttributeMandatory?DescriptionNotes
PasswordYesJWT token that authenticates the call. The browser hash inside the token identifies the voter.Get from the get-token endpoint.
TrackIDYesUnique identifier of the track being rated.10663
TrackRatingYesThe rating, 1–5. Single digit.4
StationIDNoAccepted, but the station is resolved from the track itself.

Limits

Example request

{
  "Password": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...",
  "TrackID": 10663,
  "TrackRating": 4
}

Response

The standard envelope. On success submessage is Stars updated.; typical failures are You may only star 5 items per minute. and You may not vote for this track again at this time.

Example response

{
  "message": "Success",
  "subcode": "TRUE",
  "submessage": "Stars updated."
}

Live Listeners

Returns who is listening right now, what recently finished sessions looked like, what is playing on each station, and the last ten changelog events. This is the data behind the internal monitoring dashboard.

POST https://api.ericade.net/radio/getlistening/
Administrators only. Callers must present a valid JWT in Password and the UserToken of a logged-in account whose privilege is administrator; the privilege is read from the database on every call. The address a call comes from no longer matters (until 2026-10-15 only the internal IP ranges were let in). Refusals: HTTP 401 “Invalid token” (no valid JWT) or “Not logged in” (no valid UserToken), HTTP 403 “Forbidden” (logged in, but not an administrator), HTTP 503 “Not configured” (user accounts are not set up on the server). The answer is no-store and carries no CORS header: the one caller, radio.ericade.net’s listening dashboard, asks from its server.

Request

AttributeMandatory?DescriptionNotes
PasswordYesJWT token that authenticates the call.Get from the get-token endpoint.
UserTokenYesThe user token of a logged-in administrator, as issued by /radio/v2/authenticate/login.See the v2 documentation, “Users”.
NumberOfEventsYesNumber of finished listening sessions to return. More than 100 is rejected.25
StationIDNoLimit the response to one station. When omitted, every station is included.1 = ericade.radio
2 = Best of ericade.radio
Listeners whose user agent appears in the server’s filtered-agent list, and listeners inside the excluded IP ranges, are omitted from RadioStats and StreamEvents. Sessions shorter than the configured minimum streaming time are also excluded.

Example request

{
  "Password": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...",
  "UserToken": "eyJhbGciOiJkaXIiLCJlbmMiOiJBMjU2R0NNIn0...",
  "StationID": 1,
  "NumberOfEvents": 25
}

Response

Returns four arrays in one object.

AttributeDescriptionExample
RadioStatsArray of listeners connected right now, read live from the stream server.Array[]
RadioStats => PlaytimeSeconds this listener has been connected.1842
RadioStats => PlaytimehrThe same value as a human-readable string.30 minutes
RadioStats => UserAgentThe listener’s player/user agent.VLC/3.0.20 LibVLC/3.0.20
RadioStats => IPThe listener’s IP address.203.0.113.9
RadioStats => RefererModern when the connection came through the front-end proxy, Legacy when it hit the stream server directly.Modern
RadioStats => StationID, StationNameWhich station the listener is tuned to.1 / 24/7 tracked music
RadioStats => Country, Regionname, Isp, City, ZipCached geo-lookup for the listener’s IP.Sweden
StreamEventsArray of the last NumberOfEvents completed listening sessions (logoff events).Array[]
StreamEvents => IP, Country, Regionname, Isp, City, ZipWhere the listener connected from.Sweden
StreamEvents => TimestamphrWhen the session ended, human-readable.2026-05-31 21:16:42
StreamEvents => AgentThe listener’s player/user agent.VLC/3.0.20 LibVLC/3.0.20
StreamEvents => Playtime / PlaytimehrSession length in seconds, and as a human-readable string.1842 / 30 minutes
StreamEvents => StationID, StationNameWhich station was being streamed.1 / 24/7 tracked music
StreamEvents => PlayingAtLogoffThe track that was on air when the listener disconnected.Virgill-Bratgrumbeere. Started at: Sat, 31 May 2026 21:12:03 +0000.
NowPlayingArray with one entry per station describing what is on air.Array[]
NowPlaying => Fullartist, TitleArtist and title of the current track.Virgill / Bratgrumbeere
NowPlaying => ImageImage URL for the current track.https://radio.ericade.net/images/mod.png
NowPlaying => LastPlayedTrack start time as a Unix epoch.1780262202
NowPlaying => SongTypeType/format of the current track.Amiga 4-channel module
NowPlaying => TrackID, StationID, StationNameIdentifiers for the track and its station.10147 / 1
EventsArray of the ten most recent changelog entries.Array[]
Events => TimeStamphrWhen the event was logged.2026-05-31 21:10:00
Events => ActionEvent category.Request, Star, Creationdate update
Events => LogTextHuman-readable description of the event.Listener (203.0.113.9) requested Maf - Mafland remix.
Events => StationID, StationNameThe station the event belongs to.1 / 24/7 tracked music
Responses larger than 2 MB are refused with HTTP 500 and “The generated response was outside of allowed size bounds.” Keep NumberOfEvents modest.

Example response

{
  "RadioStats": [
    {
      "Playtime": "1842",
      "Playtimehr": "30 minutes",
      "UserAgent": "VLC/3.0.20 LibVLC/3.0.20",
      "IP": "203.0.113.9",
      "Referer": "Modern",
      "StationID": "1",
      "StationName": "24/7 tracked music",
      "Country": "Sweden",
      "Regionname": "Stockholm",
      "Isp": "Example Telecom",
      "City": "Stockholm",
      "Zip": "11122"
    }
  ],
  "StreamEvents": [
    {
      "IP": "203.0.113.44",
      "Country": "Germany",
      "Regionname": "Bavaria",
      "Isp": "Example GmbH",
      "City": "Munich",
      "Zip": "80331",
      "Timestamphr": "2026-05-31 21:16:42",
      "Agent": "Winamp/5.9",
      "Playtime": "3720",
      "Playtimehr": "01 hour 02 minutes",
      "StationName": "24/7 tracked music",
      "StationID": "1",
      "PlayingAtLogoff": "Virgill-Bratgrumbeere. Started at: Sat, 31 May 2026 21:12:03 +0000."
    }
  ],
  "NowPlaying": [
    {
      "Fullartist": "Virgill",
      "Title": "Bratgrumbeere",
      "Image": "https://radio.ericade.net/images/mod.png",
      "LastPlayed": "1780262202",
      "SongType": "Amiga 4-channel module",
      "TrackID": "10147",
      "StationName": "24/7 tracked music",
      "StationID": "1"
    }
  ],
  "Events": [
    {
      "TimeStamphr": "2026-05-31 21:10:00",
      "Action": "Request",
      "LogText": "Listener (203.0.113.9) requested Maf - Mafland remix.",
      "StationName": "24/7 tracked music",
      "StationID": "1"
    }
  ]
}

Now Playing Text

Returns the current now-playing line as a single plain-text string, formatted for the stream server’s metadata field. This is not a JSON endpoint.

GET https://api.ericade.net/radio/getnowplaying/?Password=<secret>&StationID=1
Internal endpoint. Authenticated with the pre-shared ingest secret and restricted to the internal ingest IP ranges. Public callers should use Get Track with NowPlaying=1, or v2 Now Playing.

Request

Parameters are read from the query string, not from a JSON body.

AttributeMandatory?DescriptionNotes
PasswordYesPre-shared ingest secret.
StationIDYesThe station to read from.1 = ericade.radio
2 = Best of ericade.radio

Response

A bare string, truncated to 128 characters (the stream server’s metadata limit) with a trailing ellipsis if it would be longer. The Content-Type header still says application/json, so do not try to parse the body.

FormWhenExample
<artist> - <title> [<tracker type>]Normal playout.Virgill - Bratgrumbeere [Amiga 4-channel module]
NEW TRACK <artist> - <title> [<tracker type>]The track was added within the last seven days.NEW TRACK Maf - Mafland remix [Modern remix]
<artist> - <title>, now playing: "<chapter>".StationID 2, when the episode has a chapter list.ericade.radio - Flashback 97, now playing: "Love connection by Lavizh".
<artist> <title>A manual override is active in the station settings (live show, special message).ericade.radio Live from Revision 2026
<artist> - <title> [Listener request]The track is a listener request — the request prefix is stripped from the artist field.Maf - Mafland remix [Listener request]
Missing or incorrect password.The secret did not match. Note that this is returned as the body with HTTP 200.

Next Request

Returns the oldest entry in the request queue, in the shape the playout software needs in order to schedule and play it. Called by the playout automation, not by listeners.

POST https://api.ericade.net/radio/getnextrequest/
Internal endpoint. Authenticated with the pre-shared ingest secret and restricted to the internal ingest IP ranges.

Request

AttributeMandatory?DescriptionNotes
PasswordYesPre-shared ingest secret.
The queue is read across all stations and only the single oldest entry is returned. Use its StationID to tell which station it belongs to.

Response

Returns a {"Requests": [...]} object with zero or one entry.

AttributeDescriptionExample
TrackIDUnique identifier of the requested track.10663
StationIDThe station the request belongs to.1
titleTrack title.My wolf 2
fullartistComplete artist field.Arpegiator of Chryseis
GuidInternal GUID from PlayIT Live.6894ac27-abc9-4c4a-aad2-15879dda4dff
nameofrequesterDisplay name the listener chose.Caller #9
PathPlayout path of the audio file.\mods\my_wolf_2.xm
SourceOrigin of the request.Internet or Discord
CueIn / CueOutCue points in seconds.0 / 292.75
DurationFull file duration in seconds.295.1
greeting(Deprecated) Greeting supplied by the requester.

Example response

{
  "Requests": [
    {
      "TrackID": "10663",
      "StationID": "1",
      "title": "My wolf 2",
      "fullartist": "Arpegiator of Chryseis",
      "Guid": "6894ac27-abc9-4c4a-aad2-15879dda4dff",
      "nameofrequester": "Caller #9",
      "Path": "\\mods\\my_wolf_2.xm",
      "Source": "Internet",
      "CueIn": "0",
      "CueOut": "292.75",
      "Duration": "295.1",
      "greeting": ""
    }
  ]
}

Mark Request Played

Moves a request from the queue to the played pile once the playout software has aired it, and resets the artist’s eligibility timer so the same artist cannot immediately be requested again.

POST https://api.ericade.net/radio/updateplayedrequest/
Internal endpoint. Authenticated with the pre-shared ingest secret and restricted to the internal ingest IP ranges.

Request

AttributeMandatory?DescriptionNotes
PasswordYesPre-shared ingest secret.
TrackIDYesIdentifier of the track that was played.10663
StationIDYesThe station the request belonged to.1
SlotYesPlayout slot the track was aired in.3

Example request

{
  "Password": "<shared secret>",
  "TrackID": 10663,
  "StationID": 1,
  "Slot": 3
}

Response

The standard envelope. On success submessage is Successfully moved the entry to the PlayedRequests pile. Failures include Track could not be found. and Track could not be found in queue.

Check If Exists

Checks whether a file has already been imported onto a station, by matching the original file name against the album metadata. Used by the import tooling to avoid duplicates.

POST https://api.ericade.net/radio/checkifexists/
Internal endpoint. Authenticated with the pre-shared ingest secret and restricted to the internal ingest IP ranges.

Request

AttributeMandatory?DescriptionNotes
PasswordYesPre-shared ingest secret.
StationIDYesThe station to search.1
OriginalFileNameYesThe original file name to look for. Max 455 characters.!Cube - My Pixels Are Weapons.ogg

Response

The standard envelope, always with HTTP 200 — branch on message.

messagesubmessageMeaning
SuccessFile does exist on the station.Exactly one match.
FailureDoes not exist on the stationNo match.
FailureMore than one track matched the search string please narrow your search.Ambiguous — the name matched several tracks.

Update Track

The ingest endpoint. The playout software posts a track’s full metadata here every time it plays or is imported; the API creates or updates the track, splits the artist field into individual artists, maintains the play log and the now-playing row, and writes the changelog — every line of which is also an alert for the station’s administrators (see the administrators’ alerts).

POST https://api.ericade.net/radio/updatetrack/
Internal endpoint. Authenticated with the pre-shared ingest secret and restricted to the internal ingest IP ranges.

Request

AttributeMandatory?DescriptionNotes
PasswordYesPre-shared ingest secret.
StationIDYesThe station the track belongs to.1
ArtistYesFull artist field as it appears in the file, including collaborators. Max 255 characters.KRDN of Defiance and Shodan of Eternal
TitleYesTrack title. Max 255 characters.Eternal freedom 2.0
AlbumNoAlbum tag. The tracker type, batch number and original file name are parsed out of this field. Max 255 characters.OriginalName:custom.rmx Imported:2022-11-01 (TERN-oct2022-05).
GenreNoGenre tag. Max 255 characters.
YearNoYear tag. Max 255 characters.1992
CommentsNoComment field from the file. Max 8192 characters.
TagsNoComma-separated tag list. Max 255 characters.Revision, Revision 2026
GuidYesPlayIT Live GUID identifying the item. Max 255 characters.6894ac27-abc9-4c4a-aad2-15879dda4dff
PathNoPlayout path of the audio file. Max 255 characters.\mods\custom.rmx
TypeNoItem type reported by the playout software.Song
DurationNoFull file duration in seconds. Decimal; comma is accepted and converted.295.1
CueIn / CueOutNoCue points in seconds. The difference between them is the play length.0 / 292.75
Intro / Segue / OutCueNoIntro, segue and out-cue markers in seconds.0
NoFade / Sweeper / DisabledNoPlayout flags. Max 10 characters each.0 or 1
ValidFrom / ExpiresNoScheduling window for the item.
AddedNoWhen the item was added in the playout system.2022-11-01 16:19:08
TrackIDNoThe playout system’s own track identifier. Stored separately from the API’s TrackID. Max 100 characters.
TrackGroupsNoTrack group membership from the playout system. Max 4096 characters.
StartedUtc / StartedLocalNoWhen playback started, in UTC and in station-local time. Max 40 characters each.2026-05-31T21:12:03Z
How the artist field is split. Names are separated by the word and (Jeenio and Bacter and Saga Musix is three artists). In each, the part before the word of is the artist and the part after it the group, several groups separated by ^: KRDN of Defiance is KRDN, of the group Defiance. Each artist is made the first time the station meets the name and linked to the track; when a play shows that the track has changed, its links are made again — for this station only, as artists are per station. Until 2026-10-15 a name was cut at the letters “of” wherever they stood (“Hoffman” became the artist “H”), and a change on one station removed the other station’s links as well; the v2 actions CheckArtistNames and RepairArtistNames mend what that left behind.
Artists listed in the station’s ingest filter are rejected with “This track should not be added as it is in the FilteredArtistsFromIngest in the configuration for this station.”

Response

The standard envelope. On success submessage is All done. Failures include StationID field missing., Artist field missing., Title field missing. and Station configuration is not valid or the station does not exist.

Stream Events

Records a listener logon or logoff reported by the stream server, together with the geo-lookup for the listener’s IP and the track that was playing at the time. This is what feeds the listener statistics.

POST https://api.ericade.net/radio/updatestreamevent/
Internal endpoint. Authenticated with the pre-shared ingest secret and restricted to the internal ingest IP ranges.

Request

AttributeMandatory?DescriptionNotes
PasswordYesPre-shared ingest secret.
EventYesFree-text description of the event. Max 255 characters. An empty value is rejected with “Event-text needed.”Listener disconnected
EventtypeYesLogon or Logoff. On logon the IP is added to the geo cache if it is not already known.Logoff
StreamIDYesThe stream the event belongs to. Matches the StationID. Up to 3 digits.1
IPYesThe listener’s IP address. Max 255 characters.203.0.113.9
PlaytimeNoSession length in seconds. Up to 7 digits.1842
AgentNoThe listener’s player/user agent. Max 255 characters.VLC/3.0.20 LibVLC/3.0.20
CountryNoCountry name. Max 40 characters.Sweden
Regionname, City, Zip, IspNoRemaining geo fields. Max 255 characters each.Stockholm
IdentifierNoOpaque session identifier from the stream server. Max 255 characters.
Events from user agents in the filtered-agent list, and from IPs inside the excluded ranges, are accepted but not stored — the response is still Success.

Example request

{
  "Password": "<shared secret>",
  "Eventtype": "Logoff",
  "Event": "Listener disconnected",
  "StreamID": 1,
  "IP": "203.0.113.9",
  "Playtime": 1842,
  "Agent": "VLC/3.0.20 LibVLC/3.0.20",
  "Country": "Sweden",
  "Regionname": "Stockholm",
  "City": "Stockholm",
  "Zip": "11122",
  "Isp": "Example Telecom"
}

Response

The standard envelope. On success submessage is All done.

Disabled Endpoints

These URLs still exist under /radio/ but do not perform any work. They are listed here so that callers do not mistake their responses for transient errors.

EndpointStatusBehaviour
/radio/updatetrackdates/DisabledReturns the plain string This function is disabled. and stops. It used to remap a track’s creation date by GUID or path; it will stay disabled until station 2 data can be remapped safely.
/radio/populatepodcasts/DisabledReturns the plain string Not in use right now and stops.
/radio/repairdbtracking/Not implementedThe backing method no longer exists, so the call fails server-side and returns no usable body. Do not call it.