Evenings.fmEvenings Docs

API

Getting Started with the Evenings API

Updated

We built the Evenings API so you can run your station your way, on your own site as well as ours. This guide covers the endpoints most stations start with, how to authenticate, and how to make your first request.

Know the base URL

Every endpoint lives under one base URL:

https://api.evenings.co/v1

Requests and responses use JSON, except file uploads, which use multipart/form-data.

Start with three endpoints

EndpointWhat it gives youAuth
GET /v1/streams/{slug}/publicWhat's on air, whether the station is live, listener count and the audio stream URL. See the Streams API.None
GET /v1/stations/{slug}/eventsThe station's published schedule. See the Events API.None
GET /v1/tracksYour station's tracks, newest first. See the Tracks API.API key

{slug} is the last part of a station's address. For Sample Radio at evenings.fm/sample-radio, the slug is sample-radio.

Choose how to authenticate

Each endpoint expects one of three kinds of access:

AccessWhat to sendUsed by
PublicNothingStream info, stream status, published events
API keyAuthorization: Bearer YOUR_API_KEYTracks, and the listener count for your own station
Session tokenAuthorization: Bearer <session token>Publishing and unpublishing tracks

An API key belongs to one station and only ever reaches that station's data. Generate yours on the Account tab.

A session token is what our dashboard sends while you're signed in. It expires after an hour, so it isn't a good fit for scripts or servers. Use your API key wherever an endpoint accepts it.

Make your first request

Ask for a station's stream info. It's public, so you can try it straight from a terminal:

curl https://api.evenings.co/v1/streams/garage/public

The response describes whatever is on air at that moment:

{
  "id": "k9Xp2mQr",
  "name": "Tuesday Sessions",
  "host": "DJ Name",
  "url": "https://example.com",
  "description": "Weekly vibes",
  "streamUrl": "https://media.evenings.co/s/k9Xp2mQr",
  "image": "https://cdn.evenings.co/img/abc.jpg",
  "online": true,
  "listeners": 12
}

streamUrl is the audio to play, and online tells you whether anything is playing on it. name, host, description and image come from the scheduled show, the Always On track or your station, depending on what's on air. The Streams API reference explains each field.

Then try an endpoint that needs your API key:

curl https://api.evenings.co/v1/tracks \
  -H "Authorization: Bearer YOUR_API_KEY"

This returns up to 100 of your tracks as a JSON array, with the total count in the x-total response header.

Read errors

A 4xx status means we couldn't act on the request as sent: a missing or invalid key returns 401, an unknown station or track returns 404, and a request over the rate limit returns 429. A 5xx status is a problem on our side.

Every error comes back as JSON with the same two fields:

{
  "title": "No resource on the horizon 🌞",
  "error": "We couldn't find that track on your station. Check the track ID."
}
  • error says what happened and what to do next. It's the field to show people or write to your logs.
  • title is a short line in our voice, set by the status code alone. Don't parse it or match on it, because we may change the wording.

A few errors add a field alongside these two. The text blast limit, for example, also returns retryAfter, the number of seconds to wait. Let the status code decide what your code does next, and use error to tell people why. Each reference page lists the errors its endpoints return, with the exact bodies.

Since October 2026, every error uses this shape. Before then, some bodies put the message in message and some were plain text, so if your code reads message or the raw body text, switch it to read error.

Before you ship

  • Stay inside the rate limits. Every request to /v1 counts toward a limit of 100 requests per minute per IP address. Three public endpoints, List station events, Get event and Get stream status, also have a tighter limit of 50 requests per minute per IP. Going over returns 429 with { "title": "Let the tide settle 🌞", "error": "We've received too many requests from your IP address. Try again after the number of seconds in the Retry-After header." } and a Retry-After header that gives the number of seconds to wait.
  • Know whose IP counts. When a player on your website calls the API from your listeners' browsers, each listener has their own allowance. When your server calls the API on behalf of every visitor, they all share your server's allowance, so cache on your side.
  • Poll gently. Stream info is cached for 10 seconds or more, so polling more often than every 10 seconds won't show changes any sooner.
  • Keep your API key on a server. Anyone with the key can upload, edit and delete your station's tracks. The public endpoints need no key, so a player or schedule embed in a web page never needs one.

Next steps

The Streams API covers players and live status, the Events API covers your schedule, and the Tracks API covers your library. If you build something with the API, send it to us at contact@evenings.email. We'd like to see it, and that's also the address to use if a request doesn't behave the way this guide says it should.