Skip to content

Latest commit

 

History

History
197 lines (149 loc) · 12 KB

api-contracts.md

File metadata and controls

197 lines (149 loc) · 12 KB

API Contracts

TuneCamp exposes a RESTful API for webapp–backend communication, plus dedicated endpoints for ActivityPub and the Subsonic protocol. The full OpenAPI specification is in openapi.yml.

Authentication

Most endpoints require a JWT (JSON Web Token) in the Authorization header:

Authorization: Bearer <token>

Obtain a token by posting credentials to POST /api/auth/login.


Core Endpoints

Authentication (/api/auth)

Method Path Description
POST /api/users/register Register a new user
POST /api/auth/login Authenticate and receive a JWT
GET /api/auth/status Return the current session and user profile

Music Catalog (/api/catalog, /api/tracks, /api/albums)

Method Path Description
GET /api/albums List all local albums. Returns status (draft | published) and is_release (boolean) to distinguish library content from official releases
GET /api/albums/:id Album details including the track list
GET /api/artists List all artists
POST /api/tracks Create a track from metadata (a link, or a row awaiting its file). The audio is not fetched: the track is created with no file_path until a file is uploaded for it. There is no localize option here — this server does not download audio from streaming platforms
GET /api/tracks List tracks visible to the caller. Each row carries downloadable: whether THIS viewer may take the file, not just stream it (clients offering a download button read it instead of guessing)
GET /api/tracks/:id Track metadata
GET /api/tracks/:id/stream Binary audio stream (supports Range for cloud tracks)
GET /api/tracks/:id/download Download a single track's local audio file. Gated by the release's distribution mode: paid content needs an unlock code (?code=), a recorded purchase or an active subscription (402 otherwise), streaming-only and external-showcase releases answer 403. Staff, the owner and the linked artist bypass it
POST /api/tracks/:id/localize Admin-only: copy a cloud-backed track (a gdrive:// path) into a durable local file. Streaming platforms are refused with 400 — use Sidecamp
GET /api/albums/:id/download Download a ZIP of the album's local audio files (skips streaming/linked tracks). Same distribution-mode gate as the single-track route
GET /api/releases/:id/download Download a ZIP of a release's local audio files. Resolves numeric id or slug; private releases gated to owner/admin, and the same distribution-mode gate as the single-track route applies
GET /api/waveform/:id Waveform data for visualisation
GET /api/releases/:id/artwork/:filename Serve additional release artwork securely

Free Samples (/api/samples)

Method Path Description
GET /api/samples List approved samples. mine=true scopes to the caller's own uploads (any status); q filters by search term
GET /api/samples/moderation/pending Root-admin/admin/super-user: list samples awaiting curation
GET /api/samples/:id Sample metadata
GET /api/samples/:id/download Download the sample audio file. Supports ?token= query auth (approved samples are public; pending samples require the owner or a moderator)
POST /api/samples Upload a sample (multipart/form-data: file, title, description, bpm, musicalKey, license, attributionName, tags). Starts in pending status
PUT /api/samples/:id Update sample metadata (owner or moderator)
DELETE /api/samples/:id Delete a sample (owner or moderator)
POST /api/samples/:id/approve Root-admin/admin/super-user: approve a pending sample
POST /api/samples/:id/reject Root-admin/admin/super-user: reject a pending sample with optional notes

Free samples are not store assets: no price, no purchase flow, no credits. License is one of cc0, cc-by, cc-by-sa, royalty-free. Upload is reachable from /publish; managing your own uploads is under the "Samples" tab on /my-music; moderation is under "Sample Curation" on /admin.

Sample Packs (/api/sample-packs)

Method Path Description
GET /api/sample-packs List approved packs. mine=true scopes to the caller's own packs (any status); q filters by search term
GET /api/sample-packs/moderation/pending Root-admin/admin/super-user: list packs awaiting curation
GET /api/sample-packs/:id Pack metadata plus its member samples
GET /api/sample-packs/:id/cover Pack cover image; falls back to a generated placeholder SVG if none is set
POST /api/sample-packs Upload multiple files at once as a pack (multipart/form-data: files[], title, description, license, attributionName). Same publish gate and auto-approve rules as /api/samples; starts in pending unless auto-approved
POST /api/sample-packs/:id/cover Set/replace the pack cover image (multipart/form-data: cover). Owner/moderator only
PUT /api/sample-packs/:id Update pack metadata (owner or moderator)
DELETE /api/sample-packs/:id Delete a pack and all its member samples (owner or moderator)
POST /api/sample-packs/:id/approve Root-admin/admin/super-user: approve a pending pack (cascades to its samples)
POST /api/sample-packs/:id/reject Root-admin/admin/super-user: reject a pending pack with optional notes

A packed sample (samples.pack_id set) is excluded from the public /api/samples listing — it only surfaces through its pack.

Collab (/api/collab)

All routes require login. See COLLAB.md for the full feature writeup.

Method Path Description
GET /api/collab List shared projects. mine=true scopes to the caller's own
GET /api/collab/:id Project metadata plus its versions and stems
POST /api/collab Create a project (requires canPublishContent)
DELETE /api/collab/:id Delete a project and its stems (owner only)
POST /api/collab/:id/versions Save an append-only version snapshot (state, optional note)
POST /api/collab/:id/stems Upload an audio stem (multipart/form-data: file, optional name)
GET /api/collab/:id/stems/:stemId/download Stream a stem's audio
DELETE /api/collab/:id/stems/:stemId Delete a stem (stem author or project owner)

Payments & Monetisation (/api/payments)

Method Path Description
POST /api/payments/stripe/create-session Create a Stripe Checkout session for fiat purchases
POST /api/payments/stripe/create-trackcap-session Create a Stripe Checkout session to buy extra track-upload slots
GET /api/payments/onramp-config Stripe Crypto Onramp configuration
POST /api/payments/verify Verify an on-chain transaction (ETH/USDC) on Base
GET /api/payments/download/:trackId?code=... Download a purchased track via unlock code
GET /api/payments/rate/USD Current ETH/USD exchange rate

Storage & Cloud (/api/storage)

Method Path Description
GET /api/storage/gdrive/auth Start the Google Drive OAuth2 flow
GET /api/storage/gdrive/files List files and folders on Google Drive
POST /api/storage/gdrive/import Import a Drive file as a gdrive:// reference
POST /api/storage/gdrive/localize/:id Permanently download a cloud file to the local server

Metadata & External Search (/api/metadata)

Method Path Description
GET /api/metadata/search?q=... Search album metadata across external providers (MusicBrainz, Discogs, iTunes, TheAudioDB)
GET /api/metadata/lyrics?artist=...&title=... Fetch song lyrics via Lyrics.ovh
POST /api/metadata/apply Apply selected metadata to a local track

Social, Comments & Posts (/api/artists, /api/comments, /api/ap)

Method Path Description
GET /api/artists/:id/posts List an artist's public posts
POST /api/admin/posts Create a new post (admin only)
GET /api/comments/track/:trackId List comments for a specific track
POST /api/comments/track/:trackId Add a comment (requires authentication)
GET /api/ap/timeline/:artistId Recent activity from followed actors
GET /api/ap/users/:slug ActivityPub profile (actor) for a local user
POST /api/ap/inbox Receive incoming remote ActivityPub messages
POST /api/releases/:id/report Report a release for copyright or inappropriate content
GET /api/admin/reports List all active release reports (admin only)
DELETE /api/admin/reports/:id Resolve or dismiss a report (admin only)

Administration (/api/admin)

Method Path Description
GET /api/admin/system/users List registered users (admin only)
POST /api/admin/system/rescan Trigger a full library rescan
POST /api/admin/upload/tracks Store one or more audio files and scan them into the library (admin/artist only). releaseSlug links them to a release; artist/album name the container. title and trackNum set one track's title and position and are honoured only when a single file is sent — with several files each one keeps its own tags. Used by the release editor to fill an imported tracklist, whose files are rarely tagged the way the release lists them
POST /api/admin/upload/additional-artworks Upload multiple additional artworks/booklets for a release (admin/artist only)
GET /api/admin/stats Server and database usage statistics
GET /api/admin/system/resources Live process/host resource snapshot — CPU, memory, host RAM, SQLite DB size, and running background tasks (root admin only)
GET /api/admin/storage/overview Instance-wide disk usage and per-user breakdown (root admin only)

P2P content acquisition (Soulseek, BitTorrent, yt-dlp) has moved out of the backend into the Sidecamp desktop app; the former /api/admin/torrents* endpoints no longer exist.

Radio (/api/radio)

A single always-on station that streams the instance's catalog. Start/stop is admin-only; the stream and feeds are public.

Method Path Description
GET /api/radio Current station status (playing track, listener count)
POST /api/radio/start Start the station (admin only)
POST /api/radio/stop Stop the station (admin only)
GET /api/radio/stream.m3u M3U playlist for external players
GET /api/radio/feed.rss RSS feed of the station
GET /api/radio/hls/:file HLS playlist/segments for in-browser playback

Third-Party Protocols

Subsonic API (/rest)

TuneCamp implements the Subsonic protocol (v1.16.1) for compatibility with existing mobile clients such as DSub, Symfonium, Tempo, and Substreamer.

  • Base path: /rest/*.view
  • Supported methods include: getAlbumList, getMusicDirectory, stream, and more.

See SUBSONIC.md for the full compatibility table.

Model Context Protocol (/api/mcp)

TuneCamp implements MCP so that external AI clients can query the catalog and server statistics.

Method Path Description
GET /api/mcp/sse Open the async SSE channel. Requires Bearer tc_... authentication
POST /api/mcp/message Send a JSON-RPC request from client to server

See mcp-setup-guide.md for client configuration.


Response Format

All API responses (except audio streams) are JSON. On error, the server returns an appropriate HTTP status code and an error object:

{
  "error": "Descriptive error message"
}