Skip to content
HILLS API v1 Early access

API reference

Sandbox

Test the whole lifecycle with a sandbox key: simulate the review of sandbox releases.

Test the whole lifecycle with a sandbox key: simulate the review of sandbox releases.

Base URL https://app.hillsmusic.com/api/v1. Every request sends an API key: Authorization: Bearer hm_live_… (production) or hm_test_… (sandbox).

  • Simulate the review of a sandbox release (sandbox keys only)

Simulate the review of a sandbox release (sandbox keys only)

POST /api/v1/sandbox/releases/{id}/simulate · Scope: ddex:write or catalog:read · Sandbox keys only (production keys get 403 sandbox_only).

With a sandbox key (hm_test_…): moves a sandbox release as if HILLS staff had decided — approve (→ approved), reject (→ changes_requested, with your reason) or live (→ approved and live) — so you can test status polling (GET /releases/{id}, GET /ddex/{id}) end to end. Nothing is sent anywhere. A production key gets 403 sandbox_only; a production release is never found (404). catalog:read works too.

Deprecated: The status fields in the old words (status on releases, stores[key].state on each store, status and previous_status in simulate answers) are removed on April 30, 2027. Use release_status and delivery_state for the release, stores[key].status for each store, and in simulate answers release_status, delivery_state and previous_release_status instead. Until then answers carry Deprecation and Sunset headers. What changes

Parameters

Parameter In Type Required Description
id path integer Yes The sandbox release (release_id from GET /ddex/{id} items).

Request body

JSON.

Field Type Required Description
outcome approve | reject | live Yes The decision to simulate.
reason string No Rejection reason to echo back (reject).

Example request

curl -X POST "https://app.hillsmusic.com/api/v1/sandbox/releases/912/simulate" \
  -H "Authorization: Bearer $HILLS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"outcome":"approve"}'

Response 200

{
  "data": {
    "id": 912,
    "status": "approved",
    "previous_status": "pending",
    "reason": null,
    "sandbox_expires_at": "2026-11-06T09:00:00Z",
    "environment": "sandbox",
    "release_status": "approved",
    "delivery_state": "not_started",
    "previous_release_status": "in_review"
  }
}

Errors

Status When
400 invalid: a parameter is wrong; field names it.
401 unauthenticated, invalid_key, key_revoked or key_expired.
403 insufficient_scope: the key lacks the scope; scope names it. account_inactive or api_not_in_plan. sandbox_only: a production key (hm_live_…).
404 not_found: no such thing, or not yours (or not in the key’s environment).
409 invalid_state: The release’s status doesn’t allow this outcome (see the outcomes table).
429 rate_limited: wait Retry-After seconds.

Ready to integrate?

Request API access and we get back to you within 1–3 business days.