NextUp API (1.3.0)

Download OpenAPI specification:Download

An API for working with the CHIRP Radio music library

Authentication

Bearer

Most endpoints require an Authorization: Bearer <token> header, where token is the value retrieved from authorizing against the /token endpoint.

Security Scheme Type HTTP
HTTP Authorization Scheme bearer
Bearer format "JWT"

Get an authorization token

Authenticate with email and password to retrieve a JSON Web Token (JWT) you can use to authorize against other API endpoints.

Request Body schema:
email
required
string
password
required
string

Responses

Request samples

Content type
{
  • "email": "string",
  • "password": "string"
}

Response samples

Content type
application/json
{
  • "password_reset_required": true,
  • "message": "string",
  • "email": "string"
}

Search the library

Search for an album, track, or artist, or search the text of a review

Authorizations:
query Parameters
term
string

The search term

limit
integer [ 1 .. 100 ]
Default: 50

The number of results to return.

offset
integer
Default: 0

The offset of the first album to return. Use with limit to get the next page of results.

index
string
Enum: "album" "artist" "track"

Limit the search and results to albums, artists, or tracks

type
string
Deprecated
Enum: "album" "artist" "track"

Use index instead

album[is_compilation]
boolean
album[label]
string
album[local]
string
Enum: "any" "current" "classic"
album[rotation]
string
Enum: "any" "heavy" "light"
album[year]
integer
track[duration][gte]
integer

Minimum track length in milliseconds

track[duration][lte]
integer

Maximum track length in milliseconds

track[is_recommended]
boolean

List users

Retrieve a list of users in the system. Returns different data based on user permissions:

  • Regular authenticated users: Get basic user info (first_name, last_name, __key)
  • Volunteer coordinators & superusers: Get full user objects with all fields
Authorizations:

Responses

Response samples

Content type
application/json
Example
[ ]

Create a new user

Create a new user account. Requires superuser privileges or volunteer coordinator role. A temporary password will be generated and returned.

Authorizations:
Request Body schema: application/json
email
required
string <email>
first_name
required
string
last_name
required
string
dj_name
string
roles
Array of strings
Items Enum: "dj" "music_director" "traffic_log_admin" "reviewer" "volunteer_coordinator"
is_active
boolean
Default: true

Responses

Request samples

Content type
application/json
{
  • "email": "user@example.com",
  • "first_name": "string",
  • "last_name": "string",
  • "dj_name": "string",
  • "roles": [
    ],
  • "is_active": true
}

Response samples

Content type
application/json
{
  • "user": {
    },
  • "temporary_password": "string",
  • "message": "string"
}

Change password

Change password for a user by providing their email and current password

Request Body schema: application/json
email
required
string <email>
currentPassword
required
string
newPassword
required
string >= 12 characters

Responses

Request samples

Content type
application/json
{
  • "email": "user@example.com",
  • "currentPassword": "string",
  • "newPassword": "stringstring"
}

Response samples

Content type
application/json
{
  • "message": "string"
}

Update user information

Update specific fields of an existing user. Supports partial updates. Requires superuser privileges or volunteer coordinator role.

Authorizations:
path Parameters
id
required
integer

The unique identifier of the user to update

Request Body schema: application/json
email
string <email>

User's email address (must be unique)

first_name
string

User's first name

last_name
string

User's last name

dj_name
string

User's DJ name/handle

roles
Array of strings
Items Enum: "dj" "music_director" "traffic_log_admin" "reviewer" "volunteer_coordinator"

Array of user roles

is_active
boolean

Whether the user account is active

Responses

Request samples

Content type
application/json
{
  • "email": "user@example.com",
  • "first_name": "string",
  • "last_name": "string",
  • "dj_name": "string",
  • "roles": [
    ],
  • "is_active": true
}

Response samples

Content type
application/json
{
  • "__key": {
    },
  • "email": "user@example.com",
  • "first_name": "string",
  • "last_name": "string",
  • "dj_name": "string",
  • "date_joined": "2019-08-24T14:15:22Z",
  • "last_login": "2019-08-24T14:15:22Z",
  • "is_active": true,
  • "is_superuser": true,
  • "password_reset_required": true,
  • "roles": [
    ]
}

Albums

Get albums with a tag

Returns albums with a given tag

Authorizations:
query Parameters
tag
required
string
Enum: "heavy_rotation" "light_rotation" "local_current" "local_classic"
limit
integer [ 1 .. 100 ]
Default: 25

The number of albums to return.

offset
integer
Default: 0

The index of the first album to return. Use with limit to get the next set of albums.

Responses

Get recently added albums

Returns albums added after a given date and time that aren't in rotation ("library adds")

Authorizations:
query Parameters
timestamp
integer

The number of milliseconds since January 1, 1970, 00:00:00 UTC (the ECMAScript epoch, equivalent to the UNIX epoch), with leap seconds ignored. Default: 28 days before the time of the request

limit
integer [ 1 .. 100 ]
Default: 25

The number of albums to return

offset
integer
Default: 0

The index of the first album to return. Use with limit to get the next set of albums.

Responses

Get an album

Returns an album, including the artist, tracks, reviews, and comments

Authorizations:
path Parameters
album_id
required
integer

Responses

Update a track

Tag a track as explicit, recommended, or neither

Authorizations:
path Parameters
album_id
required
integer
track_num
required
integer

Responses

Artists

Get an artist

Returns an artist

Authorizations:
path Parameters
id
required
string

Responses

Get an artist's albums

Returns an artist's albums

Authorizations:
path Parameters
id
required
string

Responses

Crates

List crates

Lists all crates owned by the authorized user

Authorizations:

Responses

Get a crate

Authorizations:
path Parameters
id
required
integer

Responses

Add a crate

Authorizations:
path Parameters
id
required
integer

Responses

Update a crate

Authorizations:
path Parameters
id
required
integer

Responses

Delete a crate

Authorizations:
path Parameters
id
required
integer

Responses

Get items in a crate

Get albums, tracks, and artists in a crate

Authorizations:
path Parameters
id
required
integer
query Parameters
limit
integer [ 1 .. 100 ]
Default: 100

The number of items to return

offset
integer
Default: 0

The index of the first item to return. Use with limit to get the next set of items.

Responses

Add an item to a crate

Add a track, album, or artist to a crate by its key, or add a custom item

Authorizations:
path Parameters
id
required
integer
Request Body schema: application/json
One of
key
array

Responses

Request samples

Content type
application/json
Example
{
  • "key": [ ]
}

Response samples

Content type
application/json
{
  • "kind": "Track",
  • "encodedKey": "string",
  • "album": { },
  • "artist": { },
  • "track": { },
  • "notes": "string",
  • "categories": [
    ]
}

Remove an item from a crate

Remove the item at the specified index from the crate

Authorizations:
path Parameters
id
required
integer
index
required
integer

Zero-based index of the item to remove (i.e., the first item is 0)

Responses

Reorder an item in a crate

Move an item from one index to another

Authorizations:
path Parameters
id
required
integer
index
required
integer

Zero-based index of the item to reorder (i.e., the first item is 0)

newIndex
required
integer

New zero-based index for the item (i.e., the second item is 1)

Responses

Document

Add a comment or review

Authorizations:
Request Body schema: application/json
any

Responses

Request samples

Content type
application/json
null

Update a document

Update a document's text or author. Only the document author, users with music_director or reviewer roles, or superusers can edit documents.

Author fields are mutually exclusive: Provide either author (for registered users) or author_name (for external authors), but not both. Setting one will automatically clear the other.

Authorizations:
Request Body schema: application/json
__key
required
array

Datastore key path array for the document to update

unsafe_text
required
string
author
array

Datastore key path array for a User entity (mutually exclusive with author_name)

author_name
string

Name string for external authors (mutually exclusive with author)

Responses

Request samples

Content type
application/json
{
  • "__key": [ ],
  • "unsafe_text": "string",
  • "author": [ ],
  • "author_name": "string"
}

Response samples

Content type
application/json
{
  • "author": {
    },
  • "author_name": "string",
  • "created": "2019-08-24T14:15:22Z",
  • "doctype": "review",
  • "modified": "2019-08-24T14:15:22Z",
  • "revoked": true,
  • "subject": {
    },
  • "unsafe_text": "string",
  • "required": null
}

Delete a document

Soft delete a document by marking it as revoked. Only the document author, users with music_director or reviewer roles, or superusers can delete documents.

Authorizations:
Request Body schema: application/json
__key
required
array

Datastore key path array for the document to delete

Responses

Request samples

Content type
application/json
{
  • "__key": [ ]
}

Playlist

Get playlist events

Returns the most recently played tracks and breaks

Authorizations:
query Parameters
start
integer

The number of milliseconds since January 1, 1970, 00:00:00 UTC (the ECMAScript epoch, equivalent to the UNIX epoch), with leap seconds ignored. Default: 3 hours before the time of the request

end
integer

The number of milliseconds since January 1, 1970, 00:00:00 UTC (the ECMAScript epoch, equivalent to the UNIX epoch), with leap seconds ignored. Default: The current time

Responses

Add playlist break

Adds a break to the playlist. Only DJs and music directors can add to the playlist.

Authorizations:

Responses

Add playlist track

Adds a track to the playlist. Only DJs and music directors can add to the playlist.

Authorizations:
Request Body schema: application/json
any

Responses

Request samples

Content type
application/json
null

Add freeform playlist track

Adds a freeform track to the playlist. Only DJs and music directors can add to the playlist.

Authorizations:
Request Body schema: application/json
any

Responses

Request samples

Content type
application/json
null

Delete break or track

Delete a track or break from the playlist. Only DJs and music directors can delete from the playlist.

Authorizations:
path Parameters
id
required
integer

Responses

Update a track

Update a track on the playlist. Only DJs and music directors can update the playlist.

Authorizations:
path Parameters
id
required
integer

Responses

Get rotation plays

Returns playlist tracks from albums in rotation

Authorizations:
query Parameters
start
integer

The number of milliseconds since January 1, 1970, 00:00:00 UTC (the ECMAScript epoch, equivalent to the UNIX epoch), with leap seconds ignored. Default: 7 days before the time of the request

end
integer

The number of milliseconds since January 1, 1970, 00:00:00 UTC (the ECMAScript epoch, equivalent to the UNIX epoch), with leap seconds ignored. Default: The current time

Responses

Download CSV playlist report

Generate and download a CSV report of all playlist entries for the specified date range. Returns chronological data for both album tracks and freeform tracks with fields: date, time, station, artist, track, album, label, local. Requires music director access.

Authorizations:
query Parameters
start
required
string <date>

Start date for the report (YYYY-MM-DD)

end
required
string <date>

End date for the report (YYYY-MM-DD)

Responses

Response samples

Content type
text/csv
date,time,station,artist,track,album,label,local
2024-01-15,14:30:22,"WCXP-LP","Artist Name","Track Title","Album Title","Record Label",1
2024-01-15,14:35:15,"WCXP-LP","National Artist","Another Song","Another Album","Major Label",0

Spots

List spots

List all spots

Authorizations:

Responses

Response samples

Content type
application/json
[
  • {
    }
]

Add a spot

Only users with the traffic log admin role can add spots.

Authorizations:
path Parameters
id
required
integer
Request Body schema: application/json
object (Key)
active
boolean
title
required
string
type
required
string
Enum: "Live Read Promo" "Recorded Promo" "Live Read PSA" "Recorded PSA" "Underwriting Spot" "Pledge Liner" "Station ID"

Responses

Request samples

Content type
application/json
{
  • "__key": {
    },
  • "active": true,
  • "title": "string",
  • "type": "Live Read Promo"
}

Get a spot

Authorizations:
path Parameters
spot_id
required
integer

Responses

Response samples

Content type
application/json
{
  • "__key": {
    },
  • "id": 0,
  • "created": "2019-08-24T14:15:22Z",
  • "updated": "2019-08-24T14:15:22Z",
  • "active": true,
  • "title": "string",
  • "type": "Live Read Promo"
}

Update a spot

Only users with the traffic log admin role can update spots.

Authorizations:
path Parameters
id
required
integer

Responses

Delete a spot

Only users with the traffic log admin role can delete a spot.

Authorizations:
path Parameters
id
required
integer

Responses

Add copy to a spot

Add a bit of copy that could be read for a given spot. Only users with the traffic log admin role can add copy.

Authorizations:
path Parameters
spot_id
required
integer
Request Body schema: application/json
object (Key)
body
required
string
expire_on
string <date-time>
start_on
string <date-time>

Responses

Request samples

Content type
application/json
{
  • "__key": {
    },
  • "body": "string",
  • "expire_on": "2019-08-24T14:15:22Z",
  • "start_on": "2019-08-24T14:15:22Z"
}

Response samples

Content type
application/json
{
  • "id": 0,
  • "author": { },
  • "created": "2019-08-24T14:15:22Z",
  • "updated": "2019-08-24T14:15:22Z",
  • "__key": {
    },
  • "body": "string",
  • "expire_on": "2019-08-24T14:15:22Z",
  • "start_on": "2019-08-24T14:15:22Z"
}

Update copy

Only users with the traffic log admin role can update copy.

Authorizations:
path Parameters
id
required
integer

Responses

Delete copy

Only users with the traffic log admin role can delete copy.

Authorizations:
path Parameters
id
required
integer

Responses

Traffic Log

List traffic log entries

Returns a list of traffic log entries for the given weekday and hour. Entries that have already been read have values for "logtime", "readtime", "reader", or "__key". Entries still to be read have a random copy but no values for those properties. They can be posted to the API to be saved to the database.

Authorizations:
query Parameters
dow
integer [ 1 .. 7 ]
Default: "current weekday in Chicago"

Weekday (1 = Monday, 7 = Sunday)

hour
integer [ 0 .. 23 ]
Default: "current hour in Chicago"

Responses

Response samples

Content type
application/json
[
  • {
    }
]

Add an entry to the log

Mark the copy for a timeslot as read

Authorizations:
Request Body schema: application/json
object (Key)
readtime
string <date-time> Nullable
object (Spot)
object (SpotCopy)
object (Key)
dow
integer
hour
integer
slot
integer

Responses

Request samples

Content type
application/json
{
  • "reader": {
    },
  • "readtime": "2019-08-24T14:15:22Z",
  • "spot": {
    },
  • "spot_copy": {
    },
  • "scheduled": {
    },
  • "dow": 0,
  • "hour": 0,
  • "slot": 0
}

Response samples

Content type
application/json
{
  • "created": "2019-08-24T14:15:22Z",
  • "log_date": "2019-08-24T14:15:22Z",
  • "reader": {
    },
  • "readtime": "2019-08-24T14:15:22Z",
  • "spot": {
    },
  • "spot_copy": {
    },
  • "scheduled": {
    },
  • "dow": 0,
  • "hour": 0,
  • "slot": 0
}

Download CSV of traffic log entries

Generate and download a CSV report of traffic log entries for the specified date range. Returns data in the same format as the legacy Python implementation with fields: readtime, dow, slot_time, underwriter, title, type, excerpt (140 chars max). Requires traffic log admin access.

Authorizations:
query Parameters
start
required
string <date>

Start date for the report (YYYY-MM-DD)

end
required
string <date>

End date for the report (YYYY-MM-DD)

spot_type
string
Enum: "Live Read Promo" "Recorded Promo" "Live Read PSA" "Recorded PSA" "Underwriting Spot" "Pledge Liner" "Station ID" "Other"

Filter results to only include entries for the specified spot type

underwriter
string

Filter results to only include entries with underwriter names containing this text (case-insensitive)

Responses

Response samples

Content type
text/csv
readtime,dow,slot_time,underwriter,title,type,excerpt
2024-01-15 14:30:22,Monday,14:30,ACME Corp,Station ID,Station ID,Welcome to CHIRP Radio...

Password Reset

Request password reset

Request a password reset email. Always returns success to prevent email enumeration. Rate limited to 3 requests per minute per email address.

Request Body schema: application/json
email
required
string <email>

Email address of the user requesting password reset

Responses

Request samples

Content type
application/json
{
  • "email": "user@example.com"
}

Response samples

Content type
application/json
{
  • "success": true,
  • "message": "If that email address is registered, you will receive password reset instructions."
}

Validate reset token

Check if a password reset token is valid and not expired

query Parameters
token
required
string

The password reset token to validate

Responses

Response samples

Content type
application/json
{
  • "valid": true,
  • "error": "string"
}

Reset password with token

Reset a user's password using a valid reset token. Rate limited to 5 requests per minute.

Request Body schema: application/json
token
required
string

Valid password reset token

new_password
required
string >= 12 characters

New password (minimum 12 characters)

Responses

Request samples

Content type
application/json
{
  • "token": "string",
  • "new_password": "stringstring"
}

Response samples

Content type
application/json
{
  • "success": true,
  • "message": "Password reset successful. You can now log in with your new password."
}