Norsolia

API REFERENCE · v1

The Norsolia API

A JSON API for shows, episodes, feeds and stats. This page is generated from the same OpenAPI document the server returns at /api/v1/openapi.json.

Basics

Base URL
https://api.norsolia.com in the Core region. Each region has its own base URL, its own accounts and its own data.
Authentication
Send Authorization: Bearer <token> from a token you create in the dashboard, or sign in and use the session cookie. Cookie-based state changes also need the X-CSRF-Token header; token calls do not.
Content type
Request and response bodies are JSON, except audio and cover uploads, which send the raw file bytes.
Errors
Every error uses one shape: {"error":{"code","message"},"request_id"} plus an X-Request-Id header. Validation errors add a fields map.
Rate limits
Limits are per identifier (email, token or session) with global ceilings. Over a limit returns 429 with Retry-After.
Unknown paths
Anything under /api/ that does not exist returns 404 as JSON, including unknown versions such as /api/v9/.

A first call

curl -X POST https://api.norsolia.com/api/v1/auth/register \
  -H "Content-Type: application/json" \
  -d '{"email":"you@example.com","password":"a-long-passphrase","name":"Your name"}'

curl https://api.norsolia.com/api/v1/shows \
  -H "Authorization: Bearer nk_live_..."

Endpoints

Auth

POST/api/v1/auth/register

Create an account Creates an account immediately. Password must be at least 10 characters. No email is sent; there is nothing to confirm.

Auth: public · responses: 201, 400, 401, 409, 422, 429

POST/api/v1/auth/login

Sign in Creates a session cookie (__Host- prefix, Secure, HttpOnly, SameSite=Lax). Five failures per email trigger a 15 minute lock.

Auth: public · responses: 200, 400, 401, 422, 429

POST/api/v1/auth/logout

Sign out Ends the current session.

Auth: token or session · responses: 204, 401

Account

GET/api/v1/me

Current account Account profile, usage, CSRF token and active sessions.

Auth: token or session · responses: 200, 401

PATCH/api/v1/me

Update profile Change the display name.

Auth: token or session · responses: 200, 400, 401, 422, 429

DELETE/api/v1/me

Delete account Removes the account, its shows, episodes and files. Requires the current password.

Auth: token or session · responses: 204, 401, 422

POST/api/v1/me/password

Change password Requires the current password and a new password of at least 10 characters. Other sessions are ended.

Auth: token or session · responses: 204, 400, 401, 422, 429

GET/api/v1/sessions

Active sessions Lists active sessions for the account.

Auth: token or session · responses: 200, 401

DELETE/api/v1/sessions/{id}

End a session Ends one session by id.

Parameters

  • id (path, required) —

Auth: token or session · responses: 204, 401, 404

GET/api/v1/export

Export all data Returns a ZIP archive of the account: shows, episodes, metadata (JSON) and audio files.

Auth: token or session · responses: 200, 401

POST/api/v1/waitlist

Join a plan waitlist There are no payments. Plus and Network are request-only; this records interest.

Auth: public · responses: 201, 400, 401, 422, 429

POST/api/v1/contact

Send a message Saves a message and returns a reference number. The only contact channel is this form.

Auth: public · responses: 201, 400, 401, 422, 429

Tokens

GET/api/v1/tokens

List API tokens Lists token metadata. Secrets are never returned after creation.

Auth: token or session · responses: 200, 401

POST/api/v1/tokens

Create an API token Returns the secret once. Store it; it cannot be retrieved later.

Auth: token or session · responses: 201, 400, 401, 422, 429

DELETE/api/v1/tokens/{id}

Revoke a token Revokes one token by id.

Parameters

  • id (path, required) —

Auth: token or session · responses: 204, 401, 404

Shows

GET/api/v1/shows

List your shows Shows owned by the account.

Auth: token or session · responses: 200, 401

POST/api/v1/shows

Create a show At most three shows per account in the free beta.

Auth: token or session · responses: 201, 400, 401, 403, 409, 422, 429

GET/api/v1/shows/{slug}

Get a show Public shows are readable without authentication.

Parameters

  • slug (path, required) —

Auth: public · responses: 200, 404

PATCH/api/v1/shows/{slug}

Update a show Owner only.

Parameters

  • slug (path, required) —

Auth: token or session · responses: 200, 400, 401, 403, 404, 422, 429

DELETE/api/v1/shows/{slug}

Delete a show Removes the show, its episodes and files. Owner only.

Parameters

  • slug (path, required) —

Auth: token or session · responses: 204, 401, 403, 404

PUT/api/v1/shows/{slug}/cover

Upload a show cover PNG or JPEG up to 2 MB. The image signature is verified; the declared type is only a hint.

Parameters

  • slug (path, required) —

Auth: token or session · responses: 200, 400, 401, 403, 404, 413, 415, 422, 429

Episodes

GET/api/v1/shows/{slug}/episodes

List episodes Episodes of a show. Public shows expose published episodes without authentication.

Parameters

  • slug (path, required) —

Auth: public · responses: 200, 404

POST/api/v1/shows/{slug}/episodes

Create an episode (metadata) Creates an episode in draft. Upload the audio next with PUT .../audio.

Parameters

  • slug (path, required) —

Auth: token or session · responses: 201, 400, 401, 403, 404, 422, 429

GET/api/v1/episodes/{id}

Get an episode Published episodes of public shows are readable without authentication.

Parameters

  • id (path, required) —

Auth: public · responses: 200, 404

PATCH/api/v1/episodes/{id}

Update an episode Change metadata or status (draft, scheduled, published). Owner only.

Parameters

  • id (path, required) —

Auth: token or session · responses: 200, 400, 401, 403, 404, 422, 429

DELETE/api/v1/episodes/{id}

Delete an episode Removes the episode and its audio file. Owner only.

Parameters

  • id (path, required) —

Auth: token or session · responses: 204, 401, 403, 404

PUT/api/v1/episodes/{id}/audio

Upload episode audio MP3 or M4A up to 50 MB. For MP3 the duration is read from the frame headers; for M4A pass ?duration=<seconds>. The signature is verified.

Parameters

  • id (path, required) —
  • duration (query) — Duration in seconds (required for M4A).

Auth: token or session · responses: 200, 400, 401, 403, 404, 413, 415, 422, 429

GET/api/v1/episodes/{id}/stats

Episode play stats Daily play counts. A play is a Range request starting at byte 0, counted at most once per five minutes per (episode, hashed User-Agent). This is not a count of unique listeners.

Parameters

  • id (path, required) —
  • days (query) —

Auth: token or session · responses: 200, 401, 403, 404

Status

GET/health

Service health Liveness and dependency checks (database write/read, free disk, background task age). Returns 503 when degraded.

Auth: public · responses: 200, 503

GET/api/v1/health

Service health Same as /health, under the API prefix.

Auth: public · responses: 200, 503

GET/api/v1/status

Public status Component status from measured values: database latency, queue size, disk use percent. Account counts are not disclosed.

Auth: public · responses: 200

GET/api/v1/openapi.json

This specification The OpenAPI 3.1 document for the public API.

Auth: public · responses: 200