REST APIOverview

REST API

A human-friendly HTTP API for ONCE music distribution: upload assets, run AI detection, generate cover art, submit releases, and monitor delivery — the same capabilities, authentication, billing, and validation as the ONCE MCP server, exposed as conventional REST endpoints for developers who are not using an MCP client.

  • Base URL: https://once.app/v1
  • Machine-readable spec: GET /v1/openapi.json (OpenAPI 3.1)
  • API index: GET /v1
  • You do not need to know anything about MCP to use this API.

The MCP server (https://beta.once.app/api/mcp) remains fully supported — this REST API is an additional surface over the same platform, not a replacement. If you’re building an AI-agent integration, MCP gives you tool discovery and native auth challenges; if you’re building a backend or app, use this REST API.

Billing

Billing is identical to the MCP server: 1 credit per human song, 2 credits per AI-detected song. Submissions debit credits from the authenticated account. AI-detected songs bill at 2 credits automatically.

Quick start

BASE=https://once.app/v1
AUTH="Authorization: Bearer $ONCE_ACCESS_TOKEN"
 
# 0. Read the metadata rules (public; your inputs are validated against these)
curl $BASE/metadata-rules
 
# 1. Confirm who you are and your credit balance
curl -H "$AUTH" $BASE/me
curl -H "$AUTH" $BASE/me/credits
 
# 2. Upload cover art (small file, base64) — or generate it, see /cover-art
curl -X POST $BASE/files -H "$AUTH" -H 'Content-Type: application/json' \
  -d '{ "type": "coverArt", "file_name": "cover.jpg", "data_base64": "<base64>" }'

See Authentication for how to obtain an access token, then Uploads, AI Detection, and Releases for the full workflow.

Endpoint index

Discovery & metadata

EndpointDescription
GET /v1API index.
GET /v1/openapi.jsonOpenAPI 3.1 description of this API.
GET /v1/metadata-rulesMetadata policy hitlist (markdown; Accept: application/json for a JSON wrapper).
GET /v1/release-schemaAuthoritative required fields and an example payload.
GET /v1/pricingCredit pricing: $1/credit, per-song cost (human vs AI), discounted bulk bundles, and auto-reload. Public.

Profile & credits

EndpointDescription
GET /v1/meProfile of the authenticated user.
GET /v1/me/credits?transactions=NCredit balance, lifetime aggregates, and recent transactions.
GET /v1/me/autoreloadCurrent auto-reload configuration.
POST /v1/me/autoreloadEnable, disable, or reconfigure auto-reload (enabled, package_id/quantity, payment_method_id?, threshold_credits?).
POST /v1/credits/checkoutCreate a Stripe checkout session to buy credits (credits for a custom amount, or package_id for a discounted bundle; optional save_payment_method).

Files & uploads

EndpointDescription
POST /v1/filesUpload a small file as JSON base64.
POST /v1/files/from-urlImport a file from a public URL.
POST /v1/uploadsCreate a chunked upload session for large local files.

Audio intelligence

EndpointDescription
POST /v1/audio/ai-detectionAI Song Detector result for an uploaded file.
POST /v1/audio/acr-checkRegistry-match (Pex Search / Identify Music) check.
POST /v1/cover-artGenerate or iteratively edit AI album art.

Drafts & releases

EndpointDescription
POST /v1/draftsUpsert a work-in-progress release snapshot.
GET /v1/releases?limit=100Recent releases for the authenticated user.
POST /v1/releasesSubmit a release for distribution. Returns 201.
GET /v1/releases/:idMerged metadata for a release.
GET /v1/releases/:id/statusStore delivery + aggregate status.
GET /v1/releases/:id/jobBackground processing job state and errors.

Errors

Errors use a stable, machine-readable envelope:

{ "type": "validation_error", "code": "email_taken", "message": "..." }

type is the error family, code is a machine-readable cause (e.g. email_taken, invalid_credentials, pkce_required), and message is human-readable.

FamilyHTTPNotes
invalid_request_error400Malformed request.
authentication_error401Missing or invalid access token.
permission_error403Not allowed for this account.
not_found_error404No such resource.
conflict_error409e.g. email_taken.
validation_error422The platform rejected the content (metadata policy, weak password…).
locked_error423account_locked.
rate_limit_error429Honor the Retry-After header / retryAfterSeconds.
oauth_error400/401Token endpoint errors (invalid_grant, …).
upstream_error502The platform returned something unexpected; safe to retry with backoff.
api_error500Unexpected gateway error.

Provenance

Partners can tag requests with the X-Once-Provenance header (e.g. AIMD). The tag is forwarded to the platform and recorded on releases for analytics. See Authentication for partner onboarding.

Questions or partner access: tech@once.app.