One song in. A chart out.
A small asynchronous API for audio-to-chart generation. The website and API use the same model, queue and daily allowance.
Your API keys
Sign in to your studio first. Keys share your three-per-day allowance. Keep them on your server.
Generate a chart
Send an audio file with a unique idempotency key. Repeat the same key to recover the same job without using another daily slot. Supported: MP3, WAV, FLAC, OGG, M4A, AAC, OPUS; 25 MB and 4 minutes maximum.
export CHARTNET_KEY='your-private-key'
curl --request POST 'https://chartnet.shadowhusky-london.uk/api/v1/generate?filename=song.mp3&keys=4&difficulty=normal&rights=true' --header "Authorization: Bearer $CHARTNET_KEY" --header 'Idempotency-Key: my-song-request-001' --header 'Content-Type: application/octet-stream' --data-binary @song.mp3
# → { "id": "…", "status": "queued" }Creating a job never waits for the model to finish. Poll its status and processing events, then download the chart when status is complete.
curl -H "Authorization: Bearer $CHARTNET_KEY" https://chartnet.shadowhusky-london.uk/api/v1/jobs/JOB_ID curl -H "Authorization: Bearer $CHARTNET_KEY" 'https://chartnet.shadowhusky-london.uk/api/v1/jobs/JOB_ID/events?after=0' curl -H "Authorization: Bearer $CHARTNET_KEY" https://chartnet.shadowhusky-london.uk/api/v1/jobs/JOB_ID/chart --output chart.json
Download the OpenAPI specification → · Download a real sample chart →
Endpoints
| Method | Path | Action |
|---|---|---|
POST | /v1/generate | Upload audio and enqueue in one call |
POST | /v1/jobs | Reserve an upload from JSON metadata |
PUT | /v1/jobs/{id}/audio | Upload raw audio bytes to a reserved job |
GET | /v1/jobs | List your recent jobs |
GET | /v1/jobs/{id} | Get status and error details |
GET | /v1/jobs/{id}/events?after={eventId} | Get real processing events; poll every 2 seconds |
GET | /v1/jobs/{id}/chart | Download ChartNet JSON |
GET | /v1/jobs/{id}/audio | Read your original audio |
POST | /v1/jobs/{id}/feedback | Submit ratings, segments and optional corrected notes |
PATCH | /v1/jobs/{id}/consent | Change research consent |
DELETE | /v1/jobs/{id} | Delete audio, chart and linked feedback |
GET | /v1/me | Get remaining daily allowance |
All paths above are relative to /api. Each job and its files belong to the authenticated account. API keys cannot access another user’s jobs.
Chart format
{
"schema": "chartnet/1",
"id": "…",
"title": "My song",
"duration": 34,
"bpm": 120,
"keys": 4,
"difficulty": "normal",
"notes": [
{ "t": 1.25, "lane": 0, "dur": 0 },
{ "t": 2.0, "lane": 2, "dur": 0.5 }
],
"provenance": { "modelVersion": "…", "audioSha256": "…" }
}All times are seconds, measured from the decoded audio’s start. Lanes are zero-based. A zero duration is a tap; a positive duration is a hold. Absolute note times are authoritative; the BPM field is a summary and must not be used to resnap the chart. Difficulties: casual, easy, normal, hard, full (shown as Expert).
Limits and errors
Three charged generation attempts per account per UTC day, nine per network per day, thirty attempts across the public beta per day, twelve waiting or running jobs, and one active inference process. Failed server-side generation refunds the account slot; invalid input consumes it. The global attempt cap still counts failures to control compute abuse. All API keys share the account quota.
Use 400 for invalid input, 401 for missing authentication, 403 for forbidden requests, 404 for missing or inaccessible files, 409 for state conflicts, 413 for oversized uploads, 429 for quotas, and 503 when generation is unavailable. Errors use {"error":{"code":"…","message":"…"}}. Polling and downloads do not use a generation slot.
Feedback that can become evidence
Ratings cover timing, musicality, pattern comfort, difficulty fit and holds (1–5; omit untested aspects). Include free text, experience level, a problem segment, playback offset, and optionally corrected notes. We attach model hashes, decoder version, audio hash and generation settings on the server. Research exports require both audio and feedback consent. Corrections are reviewed and grouped by audio before evaluation splits; ratings alone are not ground-truth note labels.