Changelog
api API play_arrow Quickstart terminal Explorer verified Webhook tester history Changelog report Errors monitor_heart Status menu_book Glossary help Help

Changelog

New endpoints, fixes, schema changes, and platform updates in reverse-chronological order. Subscribe to the webhooks feed to be notified programmatically. OpenAPI 3.1 spec.

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.).
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.
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).
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).
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.
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 submittedacceptedlive). 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 (genreprimary_genre, copyright_linecopyright_holder). POST /releases now works end-to-end.
API

Multi-language metadata + cursor pagination

  • Multi-language metadata across releases, tracks, and lyrics via localized_titles / localized_descriptions as BCP-47 keyed objects. Emitted in DDEX as per-locale DisplayTitle blocks with @LanguageAndScriptCode.
  • Cursor pagination on every list endpoint. Cursor::encode / Cursor::decode helpers, opaque base64 cursors stable across inserts.
  • Idempotency-Key middleware with body-hash gate — reusing a key with a different body returns 409.
API

Rights management + per-DSP overrides + Finance surface

  • Rights management endpoints. Per-release rights matrix (streaming / download / UGC / sync / ringtone) plus per-DSP overrides for territory, monetization policies, pricing, release-date, and the full rights matrix.
  • Finance surface: Periods, Sales Reports, Tenant Statements, Payee Statements, Payouts. Every amount in minor units to avoid float drift.
  • Parent-tenant / child-tenant hierarchy for label-services and sub-distributor operators. Child tenants get their own DPID via SOBO.
API

Supply Chain config + Animated Artwork + Track properties

  • Supply Chain config: monetization policies, pricing tiers, territory clearances. GET /supply-chain/effective-config returns the resolved (default << release << per-DSP) view.
  • Animated artwork endpoints: Apple Motion (1:1 + 3:4), Spotify Canvas (9:16). MP4 / MOV / WebM / GIF accepted, max 50 MB, validated async.
  • Track properties: ISRC, audio format / bit depth / sample rate / channels / LUFS, lyric format (LRC / TTML / iTT), Dolby Atmos slot (dolby_isrc / dolby_audio_uri), explicit flag, instrumental flag, language of performance.
  • Contributors as first-class entities: Writers, Publishers, Producers, Mix & Mastering Engineers. ISNI + IPI Name Number support per contributor.
Infra

Webhooks + Ingestion + DDEX worker cron

  • Webhook publisher with HMAC-SHA256 signed events. Header X-ToneGrid-Signature: t=<ts>,v1=<hex>. Auto-retry with exponential backoff for 24h. DSP-named event catalogue (release.dsp.<slug>.submitted, .accepted, .live).
  • Multi-channel ingestion: REST JSON, DDEX XML upload, CSV, JSON bulk, SFTP drop folder. All flow through ingestion_jobs + ingestion_files with stage transitions and error reporting.
  • Cron-driven workers: webhook-retry, ingest-worker, ddex-worker, audio-validator (ffprobe). Run every minute; audio-validator every 5 min.
Foundations

API Bearer auth + sandbox + OpenAPI + status

  • api-sandbox.tonegrid.pro — identical surface to prod, separate database, no real money or DSP push.
  • Bearer token authentication via tgk_... API keys. JWT login retained for user-facing flows.
  • OpenAPI 3.1 spec at /openapi.json. Importable into Postman, Scalar, every major SDK generator.
  • Status page at /status — uptime + worker heartbeats.
  • Sandbox seeder (bin/seed-sandbox.php) — idempotent, prints copy-paste curl recipe that walks signup → release create → approve → DDEX preview → sim-mode live transitions.
  • Fixed Validator::field() regression that caused /auth/login to return 500.
  • Fixed AuditLog column-name mismatch that silently failed on every privileged action.