May 18, 2026
New
Docs
Quickstart tutorial + Webhook signature tester
Two new dev-onboarding tools, both live and linked from every topbar.
/quickstart — 9-step walkthrough, ~5 minutes
- From a brand-new sandbox account to a release delivered to every DSP, end-to-end, in copy-paste curl: signup, API-key minting, artist, release draft, track + audio upload, attach DSPs, XSD-validate, approve + watch the lifecycle, preview the literal DDEX XML.
- Every step has a request pane (curl) and an expected-response pane side-by-side, plus a per-step pro-tip callout. Sticky right-rail stepper with numbered dots highlights the active step as you scroll.
- Total time and per-step minutes summed automatically. Final wrap-up card links to the webhook tester, Explorer, and Errors catalogue for next steps.
/webhook-tester — interactive HMAC-SHA256 verifier
- Paste a webhook secret + raw body + received
X-ToneGrid-Signature header value — the page computes the expected signature with the Web Crypto API and shows a match / no-match / stale-timestamp verdict.
- Runs entirely in your browser. Secrets never hit any ToneGrid server.
- "Generate sample signature" button mints a fresh valid header so devs can test their verification code against a known-good signature.
- Algorithm explained step-by-step plus copy-paste verification snippets in PHP / Node / Python / Go, and a Common Gotchas section (raw-body vs re-parsed JSON, constant-time compare, 5-min replay tolerance, lowercase hex, etc.).
May 18, 2026
Docs
Interactive API Explorer (Scalar) + Errors catalogue
Two new top-level docs surfaces — both live, both linked from every topbar.
Explorer at /explorer
- Drops Scalar on top of the official
/openapi.json spec. Browse every endpoint (74 paths across 15 tags), inspect request/response schemas, and hit live endpoints from the browser against either Production or Sandbox via the server picker.
- Auth: paste your
tgk_ API key or JWT once and Scalar persists it across requests. Try-it requests go straight to the real API — sandbox is safe for live experimentation.
- Code-sample tabs (curl / JavaScript / Python / Go / etc.) auto-generate per endpoint.
- Light/dark theme synced with the rest of the docs via the topbar toggle.
Errors catalogue at /errors
- 46 error responses curated from the live codebase, grouped by HTTP status (400 / 401 / 402 / 403 / 404 / 409 / 413 / 415 / 422 / 429 / 500 / 502 / 503).
- Each entry: scope tag (Authentication / Catalog / DDEX / Webhooks / Billing / Idempotency / etc.), exact error message, when it fires, how to fix.
- Live search + status-jump sidebar + canonical response shape (
{ success, error, errors{} }) explained up top.
- Standalone PHP page; to add a new error: edit
errors.php's $catalog array.
May 18, 2026
API
PurgeReleaseMessage + Update re-delivery (DDEX takedowns)
ToneGrid now speaks the full ERN 4.3 takedown + update vocabulary, not just NewReleaseMessage. Hard removals (corrupt metadata, mandated takedowns) are pushed as a proper PurgeReleaseMessage. Metadata corrections re-use the original delivery's MessageThreadId so DSPs correlate them as updates rather than seeing a brand-new release (preserving stream attribution + ISRC continuity).
New generator
Ern43PurgeGenerator — produces schema-valid PurgeReleaseMessage XML (MessageHeader + PurgedRelease with ReleaseId + Title). Reuses the original NewReleaseMessage's MessageThreadId so the DSP correlates the purge with the prior delivery. Validated against the official XSD with 4 test permutations.
New endpoints
GET /releases/:uuid/ddex/purge/preview/:dsp_slug (with .xml suffix for download) — preview the literal PurgeReleaseMessage XML.
GET /releases/:uuid/ddex/purge/validate/:dsp_slug — XSD-validate the purge XML before pushing.
POST /releases/:uuid/ddex/purge + POST /releases/:uuid/ddex/purge/:dsp_slug — queue PurgeReleaseMessage delivery to every / one DSP.
POST /releases/:uuid/ddex/redeliver — re-deliver as metadata UPDATE to every attached DSP (same MessageThreadId, fresh MessageId).
Lifecycle
- Purge: row flips to
takedown_submitted → fires release.dsp.<slug>.takedown_submitted → worker pushes PurgeReleaseMessage → row becomes taken_down → fires release.dsp.<slug>.taken_down with message_type: PurgeReleaseMessage.
- Update: row flips to
update_submitted → fires release.dsp.<slug>.update_submitted → worker pushes fresh NewReleaseMessage on same MessageThreadId → row returns to live → fires release.dsp.<slug>.updated with thread_continuation: true.
- Sim mode supports both new lifecycles — takedown_submitted → taken_down and update_submitted → live transitions happen ~1 minute apart, indistinguishable from live delivery in client-facing payloads.
Schema
release_dsp_delivery.status enum extended with update_submitted + takedown_submitted. Migrated on both prod + sandbox.
- OpenAPI 3.1 spec gains 5 new paths under the
DDEX tag (74 paths total now).
May 18, 2026
API
DDEX ERN 4.3 pipeline hardening + self-validate endpoint
Replaced Ern43Generator with a schema-clean implementation that validates against the official release-notification.xsd with zero errors. Previous output had attribute-name mismatches (MessageSchemaVersionId) and structural issues that some DSPs would have rejected.
Generator now emits a much richer document — SoundRecordingEdition with PLine + RecordingMode + TechnicalDetails containing DeliveryFile (codec / bitrate kbps / channels / sample rate Hz / bit depth / Duration / File with MD5 HashSum + FileSize KB). Optional second SoundRecordingEdition for Dolby Atmos (AudioCodecType = DolbyAtmosMasterADM). Per-locale DisplayTitle & DisplayTitleText via BCP-47. DisplayArtist linked to PartyList via ArtistPartyReference. Contributor parties with ISNI + IPI Name Number. ReleaseLabelReference IDREF. Release with full PLine + CLine + Genre (GenreText + SubGenre) + ResourceGroup + LinkedReleaseResourceReference for cover. IsHiResMusic auto-flag when every track is ≥88.2 kHz / 24-bit. Optional SentOnBehalfOf for SOBO delivery. MessageControlType flips to TestMessage when supply-chain config sets is_test_delivery.
New endpoint
GET /releases/:uuid/ddex/validate/:dsp_slug — runs the generated NewReleaseMessage through libxml's schemaValidate against the official ERN 4.3 XSD and returns a validation block with { valid, errors[], xsd_path, ern_version }. Beyond-standard feature most aggregators don't expose. Use it in CI to gate release approval on schema-cleanness.
api-docs
- DDEX section rewritten end-to-end: pipeline overview, element-by-element breakdown of every section the generator emits, beyond-standard feature list, delivery lifecycle table, abridged sample NewReleaseMessage XML that validates against the official XSD, all 5 endpoints documented with curl + response samples.
- New Best Practices section with 11 subsections.
- New Changelog at
/changelog (this page).
May 17, 2026
Docs
Glossary expansion + Stage 2T security hardening
Glossary expanded from 33 to 90 terms across 8 categories (added Credits and Ops & Lifecycle). Now covers ERN 4.3 / MEAD / PIE / RIN / DPID / IPI / ISNI / SOBO / monetization policy / pricing tier / territory clearance and more.
Security
RoleMiddleware::check() now enforces — calls Response::forbidden and exits on failure instead of returning a bool callers were ignoring. Earlier versions allowed silent privilege escalation on every controller that called check() as if void.
- All
/admin/* paths and internal role names removed from public docs and the OpenAPI spec. Unauthorised hits to admin routes now return 404 instead of 403 so existence isn't confirmed.
May 15, 2026
API
Multipart audio upload + Stage 2S simulation mode
The audio upload endpoint switches to AWS S3 Multipart Upload automatically for files larger than 100 MB. Peak memory pinned at 16 MB regardless of file size. Supports up to ~160 GB per file. Aborts on failure to avoid dangling parts.
Simulated DSP delivery
Approvals on releases attached to DSPs without live credentials now run on a simulated lifecycle (~1 min submitted → accepted → live). Webhooks fire on the same channels with identical payloads. As each DSP is brought online by ToneGrid Operations, that DSP's deliveries transition seamlessly to live push — no client-side change required.
Fixed
- Release model column aliases for fields that don't exist on real schema (
genre → primary_genre, copyright_line → copyright_holder). POST /releases now works end-to-end.