Turn a piano performance (audio or video) into MIDI, MusicXML, engraved sheet music (SVG/PDF), chords and beats. Keys belong to your login; only media you host or upload and hold the rights to is processed.
Base URL
https://piano.ai2.fun/v1
1 · Submit a media URL you host (or upload a file)
curl -X POST https://piano.ai2.fun/v1/transcriptions \
-H "Authorization: Bearer sk_live_…" -H "Content-Type: application/json" \
-d '{"url":"https://cdn.example.com/perf.mp4","name":"Nocturne","style":"classical","callback_url":"https://example.com/hook"}'
# Or upload a file (up to 512 MB; audio/* or video/*)
curl -X POST https://piano.ai2.fun/v1/transcriptions \
-H "Authorization: Bearer sk_live_…" -H "Content-Type: video/mp4" \
-H "X-Filename: perf.mp4" -H "X-Song-Name: Nocturne" --data-binary @perf.mp4
2 · Poll the status (or wait for the webhook)
curl https://piano.ai2.fun/v1/transcriptions/<id> -H "Authorization: Bearer sk_live_…"
# → {"id":"…","status":"queued|running|ready|error","stage":"queued|download|transcribe|engrave|sync|done|failed","key":"E minor","bpm":107,
# "assets":{"transkun_mid":"…","transkun_musicxml":"…","score_sheet_pdf":"…","sheet_svg_pages":[…],"chords_json":"…","beats_json":"…"}}
3 · Download assets
curl -L https://piano.ai2.fun/v1/transcriptions/<id>/assets/score_sheet.pdf -H "Authorization: Bearer sk_live_…" -o sheet.pdf
Webhook
When a job finishes or fails we POST the Job object to callback_url once; failures are retried up to 6 times with exponential backoff. Header X-Piano-Signature: t=<unix>,v1=<hex> where v1 = HMAC-SHA256(webhook_secret, "<t>.<body>").
import hmac, hashlib
def verify(secret, sig_header, body: bytes):
parts = dict(p.split('=', 1) for p in sig_header.split(','))
mac = hmac.new(secret.encode(), f"{parts['t']}.".encode() + body, hashlib.sha256).hexdigest()
return hmac.compare_digest(mac, parts['v1'])
Limits & rules
- 60 calls per minute per key; 60 minutes of audio per month by default (measured by source duration). Contact us for more.
- Only media URLs you host, or direct uploads. Links from Bilibili, YouTube, Xiaohongshu, Douyin and other platforms are rejected (422).
- Submitting means you hold the rights to process the content; the sheet credit line is kept by default.
- Errors: {"error":{"code","message"}} — 401 unauthorized · 402 quota exceeded · 422 content not allowed · 429 rate limited.
- API support and higher limits: [email protected]
- OpenAPI JSON