Public developer contract

Agent-ready API docs that match the live public surface.

MusicEngine publishes a narrow, stable developer API for workspace-scoped analytics reads and secure browser-session import. This reference is generated from the same contract used for the machine-readable OpenAPI and agent discovery resources, so the public docs do not drift from the code.

Auth header

Authorization: Bearer isrc_live_...

Standard read routes

300per 60s

Write routes

60per 60s

Published responses include rate-limit headers and are scoped to the workspace that owns the presented developer API key.

Agent discovery resources

Use these entrypoints when wiring MusicEngine into agents, external tooling, or schema-aware clients. All three resources are generated from the same public API contract.

Canonical machine-readable URLs: https://musicengine.ai/docs/api.md, https://musicengine.ai/openapi.json, https://musicengine.ai/llms.txt.

Published surface coverage

MusicEngine ships more capability in the signed-in product than it currently exposes as a stable external contract. The cards below separate what is public today from what is still an internal application surface.

Best fit for API keys today

Catalogue and dashboard

Live with API keys

Read-heavy surface for the analytics dashboard: overview stats, track exports, track metadata, and historical stream rows.

Published routes

GET /api/v1/tracksGET /api/v1/tracks/[isrc]GET /api/v1/analytics/spotify/[isrc]GET /api/v1/catalogue/overview

This is intentionally output-focused. It is the cleanest public API surface today, even if it is the lowest-control part of the product.

Powerful in product, not published as generic API yet

Database and Baserow workspace

Live in app only

Users work inside an embedded Baserow workspace for tables, fields, attachments, templates, and workflow automations.

Published routes

No stable API-key routes are published for this area yet.

If an agent needs full database manipulation today, it has to act through the signed-in web app or Baserow itself rather than the public developer API.

Most operationally rich surface, still mostly internal

Distribution management

Partly exposed with API keys

The website already supports release creation, metadata updates, profile and account linking, and upload session launch.

Published routes

POST /api/v1/browser-profiles/import

The public API does not yet expose release CRUD or upload-start endpoints, even though the signed-in product already uses them internally.

Security posture

Authentication and controls

Authentication

Use the Authorization header with a Bearer token generated from Settings > API Keys. Raw keys are shown once and cannot be recovered later.

Rate limiting

Read-heavy endpoints use a 300 requests per 60 seconds policy. Always honor X-RateLimit-* and Retry-After headers instead of hard-coding assumptions.

Mutation endpoints use a stricter 60 requests per 60 seconds policy because they trigger sensitive downstream automation work.

Standard errors

CodeMeaning
200 / 201Success. The request completed successfully.
400Bad Request. Parameters or JSON payload did not pass validation.
401Unauthorized. The Authorization header is missing or the API key is invalid.
403Forbidden. The workspace does not have access to the requested public surface.
404Not Found. The requested resource does not exist inside the authenticated workspace.
429Too Many Requests. Back off and respect Retry-After and X-RateLimit-* headers.
500Internal Server Error. MusicEngine failed while processing the request.

Workspace-scoped authorization

Every published endpoint authenticates the presented API key, resolves the owning MusicEngine workspace, and scopes reads or writes to that workspace before any data access happens.

API keys hashed at rest

MusicEngine stores only a SHA-256 hash of each developer API key. The raw key is shown once at creation time and cannot be recovered later.

Encrypted browser-session imports

Imported browser cookies are encrypted at rest with per-user keys. The public import endpoint refuses requests if encryption is not configured.

Rate-limited public surface

Published routes emit X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, and Retry-After headers where applicable. Limits are enforced against a stable request principal instead of only the caller IP.

Explicit contract boundary

Only the endpoints documented here are part of the stable public agent contract. Signed-in product routes used by the web app are intentionally excluded until they are promoted to the public API.

Endpoint reference

Each endpoint below is part of the stable public contract. Parameters, request bodies, response examples, and code snippets are rendered from the shared developer API contract used by the exported OpenAPI and Markdown resources.

GET/api/v1/tracks

List monitored catalogue tracks

Returns the authenticated workspace catalogue in reverse creation order with explicit pagination metadata for exports, sync jobs, and agent memory.

Surface

catalogue

Rate limit

300 / 60s

Parameters

limitqueryinteger

Maximum number of rows to return.

offsetqueryinteger

Zero-based pagination offset.

Security notes

  • Results are filtered by the authenticated workspace user_id before query execution.
  • The response intentionally exposes only published catalogue fields and pagination metadata.

Success response 200

Paginated catalogue track list.

{
  "data": [
    {
      "track_id": "9af166df-2fe2-4ea4-bec6-a4ce775f3b30",
      "isrc": "USXXX1234567",
      "title": "Song Name",
      "artist": "Artist Name",
      "album": "Release Name",
      "release_date": "2024-01-01",
      "cover_url": "https://cdn.musicengine.ai/covers/song-name.jpg",
      "spotify_track_url": "https://open.spotify.com/track/abc123",
      "full_tracking": true,
      "created_at": "2026-03-08T10:00:00.000Z"
    }
  ],
  "pagination": {
    "total": 150,
    "limit": 50,
    "offset": 0,
    "has_more": true
  }
}

Code examples

cURL

curl --request GET 'https://musicengine.ai/api/v1/tracks?limit=50&offset=0' \
  --header 'Authorization: Bearer isrc_live_...'

Node.js

const response = await fetch('https://musicengine.ai/api/v1/tracks?limit=50&offset=0', {
  headers: {
    Authorization: 'Bearer isrc_live_...',
  },
});

const payload = await response.json();

Python

import requests

response = requests.get(
    'https://musicengine.ai/api/v1/tracks',
    headers={'Authorization': 'Bearer isrc_live_...'},
    params={'limit': 50, 'offset': 0},
)

payload = response.json()
GET/api/v1/tracks/{isrc}

Fetch a single track by ISRC

Returns the canonical catalogue record for one ISRC inside the authenticated workspace, including stored metadata and label data.

Surface

catalogue

Rate limit

300 / 60s

Parameters

isrcpathstringrequired

International Standard Recording Code for the track.

Security notes

  • The route first authenticates the API key and then queries only the matching workspace row.
  • ISRC matching is case-insensitive because the handler normalizes the path parameter to uppercase.

Success response 200

Detailed track metadata.

{
  "data": {
    "track_id": "9af166df-2fe2-4ea4-bec6-a4ce775f3b30",
    "isrc": "USXXX1234567",
    "upc": "123456789012",
    "title": "Song Name",
    "artist": "Artist Name",
    "album": "Release Name",
    "release_date": "2024-01-01",
    "duration_ms": 187000,
    "cover_url": "https://cdn.musicengine.ai/covers/song-name.jpg",
    "spotify_track_url": "https://open.spotify.com/track/abc123",
    "label": "My Label",
    "copyright_c": "(C) My Label",
    "copyright_p": "(P) My Label",
    "full_tracking": true,
    "created_at": "2026-03-08T10:00:00.000Z",
    "metadata": {}
  }
}

Code examples

cURL

curl --request GET 'https://musicengine.ai/api/v1/tracks/USXXX1234567' \
  --header 'Authorization: Bearer isrc_live_...'

Node.js

const response = await fetch('https://musicengine.ai/api/v1/tracks/USXXX1234567', {
  headers: {
    Authorization: 'Bearer isrc_live_...',
  },
});

const payload = await response.json();
GET/api/v1/analytics/spotify/{isrc}

Fetch historical stream rows for a tracked ISRC

Returns the latest daily analytics rows stored for a tracked ISRC. The payload currently includes spotify_streams and apple_streams because both metrics are stored in the same daily dataset.

Surface

catalogue

Rate limit

300 / 60s

Parameters

isrcpathstringrequired

International Standard Recording Code for the track.

daysqueryinteger

How many most-recent daily rows to return.

Security notes

  • The handler verifies the ISRC belongs to the authenticated workspace before reading analytics rows.
  • days is validated to a bounded 1-365 window to avoid unbounded response generation.

Success response 200

Recent daily analytics rows for the requested ISRC.

{
  "data": {
    "isrc": "USXXX1234567",
    "historical_data": [
      {
        "date": "2024-03-20",
        "spotify_streams": 15420,
        "apple_streams": 1200
      },
      {
        "date": "2024-03-19",
        "spotify_streams": 14900,
        "apple_streams": 1185
      }
    ]
  }
}

Code examples

cURL

curl --request GET 'https://musicengine.ai/api/v1/analytics/spotify/USXXX1234567?days=7' \
  --header 'Authorization: Bearer isrc_live_...'

Python

import requests

response = requests.get(
    'https://musicengine.ai/api/v1/analytics/spotify/USXXX1234567',
    headers={'Authorization': 'Bearer isrc_live_...'},
    params={'days': 7},
)

payload = response.json()
POST/api/v1/browser-profiles/import

Import an encrypted browser session for automation

Creates a reusable browser profile record for the authenticated workspace by storing a browser session cookie jar in encrypted form. This is the public write endpoint that seeds downstream distribution automation.

Surface

distribution

Rate limit

60 / 60s

Parameters

No path or query parameters.

Request body

Provide a human-readable profile name and at least one cookie object. Additional cookie fields are preserved, but domain, name, and value are required.

{
  "name": "DistroKid primary session",
  "cookies": [
    {
      "domain": ".spotify.com",
      "name": "sp_dc",
      "value": "...",
      "path": "/",
      "secure": true,
      "httpOnly": true
    }
  ]
}

Security notes

  • This endpoint is disabled unless cookie encryption is configured on the server.
  • Payload validation enforces bounded cookie counts and sizes before any encrypted storage occurs.

Success response 201

Browser profile created and cookie payload stored in encrypted form.

{
  "success": true,
  "message": "Browser profile and securely encrypted session cookies successfully imported.",
  "profile_id": 1234,
  "name": "DistroKid primary session"
}

Code examples

cURL

curl --request POST 'https://musicengine.ai/api/v1/browser-profiles/import' \
  --header 'Authorization: Bearer isrc_live_...' \
  --header 'Content-Type: application/json' \
  --data '{
    "name": "DistroKid primary session",
    "cookies": [
      {
        "domain": ".spotify.com",
        "name": "sp_dc",
        "value": "...",
        "path": "/",
        "secure": true,
        "httpOnly": true
      }
    ]
  }'

Node.js

const response = await fetch('https://musicengine.ai/api/v1/browser-profiles/import', {
  method: 'POST',
  headers: {
    Authorization: 'Bearer isrc_live_...',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    name: 'DistroKid primary session',
    cookies: [
      {
        domain: '.spotify.com',
        name: 'sp_dc',
        value: '...',
        path: '/',
        secure: true,
        httpOnly: true,
      },
    ],
  }),
});

const payload = await response.json();
GET/api/v1/catalogue/overview

Fetch the dashboard overview payload

Aggregates high-level workspace metrics, best tracks, and best artists into a compact payload suited to daily reporting, summaries, and agent briefings.

Surface

catalogue

Rate limit

300 / 60s

Parameters

datequerystring

Optional historical day in YYYY-MM-DD format. Defaults to the latest available day.

Security notes

  • All aggregate queries are parameterized with the authenticated workspace user_id.
  • The route exposes a compact summary payload rather than raw internal table structures.

Success response 200

Overview stats and top performers for the requested or latest day.

{
  "success": true,
  "data": {
    "stats": {
      "total_inner_catalogue_tracks": 42,
      "has_stream_data": true,
      "days_tracked": 12
    },
    "best_tracks": [
      {
        "isrc": "USXXX1234567",
        "title": "Hit Song",
        "artist": "Main Artist",
        "streams": 1500
      }
    ],
    "best_artists": [
      {
        "artist": "Main Artist",
        "streams": 4500
      }
    ]
  }
}

Code examples

cURL

curl --request GET 'https://musicengine.ai/api/v1/catalogue/overview?date=2026-03-08' \
  --header 'Authorization: Bearer isrc_live_...'

Python

import requests

response = requests.get(
    'https://musicengine.ai/api/v1/catalogue/overview',
    headers={'Authorization': 'Bearer isrc_live_...'},
    params={'date': '2026-03-08'},
)

payload = response.json()

Signed-in product surfaces

The MusicEngine web application already uses broader internal route families for Baserow workspace management and distribution operations. They are real product capabilities, but they are not published as a stable API-key contract today.

Powerful in product, not published as generic API yet

Database and Baserow workspace

Live in app only

What the product can do

  • Open the user workspace inside embedded Baserow via SSO.
  • Work directly with rows, fields, views, and attachments in the Baserow UI.
  • Add templates, configure webhooks, and trigger inspiration downloads.

Internal route families

/api/baserow/workspace-url/api/baserow/add-templates/api/baserow/setup-webhook/api/baserow/trigger-inspiration-download

If an agent needs full database manipulation today, it has to act through the signed-in web app or Baserow itself rather than the public developer API.

Most operationally rich surface, still mostly internal

Distribution management

Partly exposed with API keys

What the product can do

  • Create releases and track rows.
  • Assign releases to distributor accounts and accounts to browser profiles.
  • Update release and track metadata before upload.
  • Start interactive browser sessions and launch upload automation.

Internal route families

/api/distribution/releases/api/distribution/update-metadata/api/distribution/assign-account/api/distribution/assign-release/api/distribution/releases-by-account/api/distributor-sessions/start/api/distributor-sessions/start-upload

The public API does not yet expose release CRUD or upload-start endpoints, even though the signed-in product already uses them internally.