# Webhooks
> Endpunkte, die HILLS Music bei Ereignissen aufruft: Releases, Auslieferung, DDEX, Abrechnungen, Auszahlungen, Anfragen, Live-Support. Signiert, wiederholt.
Endpunkte, die HILLS Music bei Ereignissen aufruft: Releases, Auslieferung, DDEX, Abrechnungen, Auszahlungen, Anfragen, Live-Support. Signiert, wiederholt.
Basis-URL `https://api.hillsmusic.com/v1`. Jede Anfrage sendet einen API-Schlüssel: `Authorization: Bearer hm_live_…`.
- Webhook-Eventtypen auflisten
- Webhook-Endpunkte auflisten
- Webhook-Endpunkt anlegen
- Webhook-Endpunkt abrufen
- Webhook-Endpunkt ändern
- Webhook-Endpunkt löschen
- Webhook-Secret erneuern
- Test-Event senden
- Zustellungen eines Endpunkts auflisten
- Zustellung wiederholen
## Webhook-Eventtypen auflisten
`GET /v1/webhooks/events` · Scope: `webhooks:read` oder `webhooks:write`
Alle Eventtypen, die ein Endpunkt abonnieren kann, mit ihrer Bedeutung. Die Payloads sind in dieser Referenz unter Webhooks dokumentiert.
### Beispielanfrage
```bash
curl "https://api.hillsmusic.com/v1/webhooks/events" \
-H "Authorization: Bearer $HILLS_API_KEY"
```
### Antwort `200`
```json
{
"data": [
{
"type": "release.approved",
"label": "Release approved",
"description": "A release was approved and is queued for its stores."
}
]
}
```
### Fehler
| Status | Wann |
| --- | --- |
| 401 | unauthenticated, invalid_key, key_revoked, key_expired oder test_keys_retired. |
| 403 | insufficient_scope: Dem Schlüssel fehlt der Scope; scope nennt ihn. account_inactive oder api_not_in_plan. |
| 429 | rate_limited: Retry-After Sekunden warten. |
## Webhook-Endpunkte auflisten
`GET /v1/webhooks` · Scope: `webhooks:read` oder `webhooks:write`
Ihre Webhook-Endpunkte (höchstens 20), die ältesten zuerst. Das Secret wird nie mit ausgegeben.
### Beispielanfrage
```bash
curl "https://api.hillsmusic.com/v1/webhooks" \
-H "Authorization: Bearer $HILLS_API_KEY"
```
### Antwort `200`
```json
{
"data": [
{
"id": 7,
"url": "https://example.com/hills/webhooks",
"description": "Order system",
"events": [
"release.approved",
"delivery.store_status_changed"
],
"enabled": true,
"secret_prefix": "whsec_3f9a1c",
"created_at": "2026-10-13T09:00:00Z",
"updated_at": "2026-10-13T09:00:00Z",
"last_success_at": null,
"last_failure_at": null,
"failure_count": 0,
"disabled_at": null,
"disabled_reason": null
}
]
}
```
### Fehler
| Status | Wann |
| --- | --- |
| 401 | unauthenticated, invalid_key, key_revoked, key_expired oder test_keys_retired. |
| 403 | insufficient_scope: Dem Schlüssel fehlt der Scope; scope nennt ihn. account_inactive oder api_not_in_plan. |
| 429 | rate_limited: Retry-After Sekunden warten. |
## Webhook-Endpunkt anlegen
`POST /v1/webhooks` · Scope: `webhooks:write`
Registriert eine https-URL für die gewählten Events. Die Antwort enthält einmalig das Signing-Secret. Die URL muss öffentlich sein: Private, lokale und Metadaten-Adressen werden abgelehnt.
### Request-Body
JSON.
| Feld | Typ | Pflicht | Beschreibung |
| --- | --- | --- | --- |
| `url` | string | Ja | Wohin Events per POST gesendet werden: eine öffentliche https://-URL auf Port 443. |
| `description` | string | Nein | Eine Notiz für Sie, z. B. das System, das die Events empfängt. |
| `events` | array | Ja | Die zu sendenden Eventtypen (siehe Webhooks in dieser Referenz). |
| `enabled` | boolean | Nein | Standard true. |
### Beispielanfrage
```bash
curl -X POST "https://api.hillsmusic.com/v1/webhooks" \
-H "Authorization: Bearer $HILLS_API_KEY" \
-H "Content-Type: application/json" \
-d '{"url":"https://example.com/hills/webhooks","description":"Order system","events":["release.approved","delivery.store_status_changed"]}'
```
### Antwort `201`
```json
{
"endpoint": {
"id": 7,
"url": "https://example.com/hills/webhooks",
"description": "Order system",
"events": [
"release.approved",
"delivery.store_status_changed"
],
"enabled": true,
"secret_prefix": "whsec_3f9a1c",
"created_at": "2026-10-13T09:00:00Z",
"updated_at": "2026-10-13T09:00:00Z",
"last_success_at": null,
"last_failure_at": null,
"failure_count": 0,
"disabled_at": null,
"disabled_reason": null
},
"secret": "whsec_3f9a1c0d5e7b2a4c6e8f0a1b3c5d7e9f1a2b3c4d5e6f7a8b"
}
```
### Fehler
| Status | Wann |
| --- | --- |
| 400 | invalid: Ein Parameter ist fehlerhaft; field nennt ihn. invalid_url: Keine öffentliche https-URL auf Port 443. |
| 401 | unauthenticated, invalid_key, key_revoked, key_expired oder test_keys_retired. |
| 403 | insufficient_scope: Dem Schlüssel fehlt der Scope; scope nennt ihn. account_inactive oder api_not_in_plan. |
| 409 | too_many: Bereits 20 Endpunkte. |
| 429 | rate_limited: Retry-After Sekunden warten. |
## Webhook-Endpunkt abrufen
`GET /v1/webhooks/{id}` · Scope: `webhooks:read` oder `webhooks:write`
Ein Endpunkt mit seinem Zustand: letzter Erfolg und letzter Fehlschlag, fehlgeschlagene Versuche in Folge und warum er deaktiviert ist.
### Parameter
| Parameter | Ort | Typ | Pflicht | Beschreibung |
| --- | --- | --- | --- | --- |
| `id` | path | integer | Ja | Die ID des Endpunkts. |
### Beispielanfrage
```bash
curl "https://api.hillsmusic.com/v1/webhooks/7" \
-H "Authorization: Bearer $HILLS_API_KEY"
```
### Antwort `200`
```json
{
"data": {
"id": 7,
"url": "https://example.com/hills/webhooks",
"description": "Order system",
"events": [
"release.approved",
"delivery.store_status_changed"
],
"enabled": true,
"secret_prefix": "whsec_3f9a1c",
"created_at": "2026-10-13T09:00:00Z",
"updated_at": "2026-10-13T09:00:00Z",
"last_success_at": null,
"last_failure_at": null,
"failure_count": 0,
"disabled_at": null,
"disabled_reason": null
}
}
```
### Fehler
| Status | Wann |
| --- | --- |
| 401 | unauthenticated, invalid_key, key_revoked, key_expired oder test_keys_retired. |
| 403 | insufficient_scope: Dem Schlüssel fehlt der Scope; scope nennt ihn. account_inactive oder api_not_in_plan. |
| 404 | not_found: Existiert nicht oder gehört nicht Ihnen. |
| 429 | rate_limited: Retry-After Sekunden warten. |
## Webhook-Endpunkt ändern
`PATCH /v1/webhooks/{id}` · Scope: `webhooks:write`
Ändert URL, Beschreibung oder Events oder schaltet den Endpunkt aus und ein (enabled). Das erneute Einschalten setzt den Fehlerzähler zurück; Zustellungen, die aufgegeben wurden, während er aus war, lassen sich mit retry erneut senden.
### Parameter
| Parameter | Ort | Typ | Pflicht | Beschreibung |
| --- | --- | --- | --- | --- |
| `id` | path | integer | Ja | Die ID des Endpunkts. |
### Request-Body
JSON.
| Feld | Typ | Pflicht | Beschreibung |
| --- | --- | --- | --- |
| `url` | string | Nein | Wohin Events per POST gesendet werden: eine öffentliche https://-URL auf Port 443. |
| `description` | string | Nein | Eine Notiz für Sie, z. B. das System, das die Events empfängt. |
| `events` | array | Nein | Die zu sendenden Eventtypen (siehe Webhooks in dieser Referenz). |
| `enabled` | boolean | Nein | false schaltet ihn aus, true wieder ein. |
### Beispielanfrage
```bash
curl -X PATCH "https://api.hillsmusic.com/v1/webhooks/7" \
-H "Authorization: Bearer $HILLS_API_KEY" \
-H "Content-Type: application/json" \
-d '{"enabled":true}'
```
### Antwort `200`
```json
{
"data": {
"id": 7,
"url": "https://example.com/hills/webhooks",
"description": "Order system",
"events": [
"release.approved",
"delivery.store_status_changed"
],
"enabled": true,
"secret_prefix": "whsec_3f9a1c",
"created_at": "2026-10-13T09:00:00Z",
"updated_at": "2026-10-13T09:00:00Z",
"last_success_at": null,
"last_failure_at": null,
"failure_count": 0,
"disabled_at": null,
"disabled_reason": null
}
}
```
### Fehler
| Status | Wann |
| --- | --- |
| 400 | invalid: Ein Parameter ist fehlerhaft; field nennt ihn. invalid_url: Keine öffentliche https-URL auf Port 443. |
| 401 | unauthenticated, invalid_key, key_revoked, key_expired oder test_keys_retired. |
| 403 | insufficient_scope: Dem Schlüssel fehlt der Scope; scope nennt ihn. account_inactive oder api_not_in_plan. |
| 404 | not_found: Existiert nicht oder gehört nicht Ihnen. |
| 429 | rate_limited: Retry-After Sekunden warten. |
## Webhook-Endpunkt löschen
`DELETE /v1/webhooks/{id}` · Scope: `webhooks:write`
Löscht den Endpunkt und sein Zustellprotokoll. Es wird nichts mehr an ihn gesendet.
### Parameter
| Parameter | Ort | Typ | Pflicht | Beschreibung |
| --- | --- | --- | --- | --- |
| `id` | path | integer | Ja | Die ID des Endpunkts. |
### Beispielanfrage
```bash
curl -X DELETE "https://api.hillsmusic.com/v1/webhooks/7" \
-H "Authorization: Bearer $HILLS_API_KEY"
```
### Antwort `200`
```json
{
"ok": true
}
```
### Fehler
| Status | Wann |
| --- | --- |
| 401 | unauthenticated, invalid_key, key_revoked, key_expired oder test_keys_retired. |
| 403 | insufficient_scope: Dem Schlüssel fehlt der Scope; scope nennt ihn. account_inactive oder api_not_in_plan. |
| 404 | not_found: Existiert nicht oder gehört nicht Ihnen. |
| 429 | rate_limited: Retry-After Sekunden warten. |
## Webhook-Secret erneuern
`POST /v1/webhooks/{id}/roll-secret` · Scope: `webhooks:write`
Erzeugt ein neues Signing-Secret; das alte ist sofort ungültig. Das neue Secret steht nur in dieser Antwort.
### Parameter
| Parameter | Ort | Typ | Pflicht | Beschreibung |
| --- | --- | --- | --- | --- |
| `id` | path | integer | Ja | Die ID des Endpunkts. |
### Beispielanfrage
```bash
curl -X POST "https://api.hillsmusic.com/v1/webhooks/7/roll-secret" \
-H "Authorization: Bearer $HILLS_API_KEY"
```
### Antwort `200`
```json
{
"endpoint": {
"id": 7,
"url": "https://example.com/hills/webhooks",
"description": "Order system",
"events": [
"release.approved",
"delivery.store_status_changed"
],
"enabled": true,
"secret_prefix": "whsec_3f9a1c",
"created_at": "2026-10-13T09:00:00Z",
"updated_at": "2026-10-13T09:00:00Z",
"last_success_at": null,
"last_failure_at": null,
"failure_count": 0,
"disabled_at": null,
"disabled_reason": null
},
"secret": "whsec_3f9a1c0d5e7b2a4c6e8f0a1b3c5d7e9f1a2b3c4d5e6f7a8b"
}
```
### Fehler
| Status | Wann |
| --- | --- |
| 401 | unauthenticated, invalid_key, key_revoked, key_expired oder test_keys_retired. |
| 403 | insufficient_scope: Dem Schlüssel fehlt der Scope; scope nennt ihn. account_inactive oder api_not_in_plan. |
| 404 | not_found: Existiert nicht oder gehört nicht Ihnen. |
| 429 | rate_limited: Retry-After Sekunden warten. |
## Test-Event senden
`POST /v1/webhooks/{id}/test` · Scope: `webhooks:write`
Reiht ein webhook.test-Event für diesen Endpunkt ein, unabhängig von seinen abonnierten Events, und signiert es wie jedes andere. Das Ergebnis erscheint in den Zustellungen.
### Parameter
| Parameter | Ort | Typ | Pflicht | Beschreibung |
| --- | --- | --- | --- | --- |
| `id` | path | integer | Ja | Die ID des Endpunkts. |
### Beispielanfrage
```bash
curl -X POST "https://api.hillsmusic.com/v1/webhooks/7/test" \
-H "Authorization: Bearer $HILLS_API_KEY"
```
### Antwort `202`
```json
{
"delivery": {
"id": 1042,
"endpoint_id": 7,
"event": "webhook.test",
"event_id": "5d0c2b7e-8a43-4c4e-9f1e-2f0b9a6c1d33",
"attempt": 0,
"status": "pending",
"response_status": null,
"response_ms": null,
"next_attempt_at": "2026-10-13T09:05:00Z",
"error": null,
"created_at": "2026-10-13T09:05:00Z",
"delivered_at": null,
"payload": {
"id": "5d0c2b7e-8a43-4c4e-9f1e-2f0b9a6c1d33",
"type": "release.approved",
"api_version": "v1",
"occurred_at": "2026-10-13T09:05:00Z",
"account_id": 12,
"data": {
"release": {
"id": 812,
"title": "Midnight Run"
}
}
}
}
}
```
### Fehler
| Status | Wann |
| --- | --- |
| 401 | unauthenticated, invalid_key, key_revoked, key_expired oder test_keys_retired. |
| 403 | insufficient_scope: Dem Schlüssel fehlt der Scope; scope nennt ihn. account_inactive oder api_not_in_plan. |
| 404 | not_found: Existiert nicht oder gehört nicht Ihnen. |
| 409 | endpoint_disabled: Der Endpunkt ist deaktiviert. |
| 429 | rate_limited: Retry-After Sekunden warten. |
## Zustellungen eines Endpunkts auflisten
`GET /v1/webhooks/{id}/deliveries` · Scope: `webhooks:read` oder `webhooks:write`
Was in den letzten 30 Tagen an den Endpunkt gesendet wurde, das Neueste zuerst: Payload, Versuche, letzter HTTP-Status mit Zeitpunkt und der Fehler.
### Parameter
| Parameter | Ort | Typ | Pflicht | Beschreibung |
| --- | --- | --- | --- | --- |
| `id` | path | integer | Ja | Die ID des Endpunkts. |
| `status` | query | `pending` \| `succeeded` \| `failed` | Nein | Nur diese. |
| `event` | query | string | Nein | Nur dieser Eventtyp. |
| `limit` | query | number | Nein | 1–100, Standard 50. |
| `before` | query | number | Nein | Zustellungen, die älter sind als diese Zustellungs-ID (die nächste Seite). |
### Beispielanfrage
```bash
curl "https://api.hillsmusic.com/v1/webhooks/7/deliveries?status=failed" \
-H "Authorization: Bearer $HILLS_API_KEY"
```
### Antwort `200`
```json
{
"data": [
{
"id": 1042,
"endpoint_id": 7,
"event": "release.approved",
"event_id": "5d0c2b7e-8a43-4c4e-9f1e-2f0b9a6c1d33",
"attempt": 1,
"status": "succeeded",
"response_status": 200,
"response_ms": 184,
"next_attempt_at": "2026-10-13T09:05:00Z",
"error": null,
"created_at": "2026-10-13T09:05:00Z",
"delivered_at": "2026-10-13T09:05:01Z",
"payload": {
"id": "5d0c2b7e-8a43-4c4e-9f1e-2f0b9a6c1d33",
"type": "release.approved",
"api_version": "v1",
"occurred_at": "2026-10-13T09:05:00Z",
"account_id": 12,
"data": {
"release": {
"id": 812,
"title": "Midnight Run"
}
}
}
}
],
"has_more": false
}
```
### Fehler
| Status | Wann |
| --- | --- |
| 400 | invalid: Ein Parameter ist fehlerhaft; field nennt ihn. |
| 401 | unauthenticated, invalid_key, key_revoked, key_expired oder test_keys_retired. |
| 403 | insufficient_scope: Dem Schlüssel fehlt der Scope; scope nennt ihn. account_inactive oder api_not_in_plan. |
| 404 | not_found: Existiert nicht oder gehört nicht Ihnen. |
| 429 | rate_limited: Retry-After Sekunden warten. |
## Zustellung wiederholen
`POST /v1/webhooks/{id}/deliveries/{delivery_id}/retry` · Scope: `webhooks:write`
Sendet dasselbe Event (gleiche ID und Payload) jetzt erneut an den Endpunkt.
### Parameter
| Parameter | Ort | Typ | Pflicht | Beschreibung |
| --- | --- | --- | --- | --- |
| `id` | path | integer | Ja | Die ID des Endpunkts. |
| `delivery_id` | path | integer | Ja | Die ID der Zustellung. |
### Beispielanfrage
```bash
curl -X POST "https://api.hillsmusic.com/v1/webhooks/7/deliveries/1042/retry" \
-H "Authorization: Bearer $HILLS_API_KEY"
```
### Antwort `202`
```json
{
"delivery": {
"id": 1042,
"endpoint_id": 7,
"event": "release.approved",
"event_id": "5d0c2b7e-8a43-4c4e-9f1e-2f0b9a6c1d33",
"attempt": 1,
"status": "pending",
"response_status": 200,
"response_ms": 184,
"next_attempt_at": "2026-10-13T09:05:00Z",
"error": null,
"created_at": "2026-10-13T09:05:00Z",
"delivered_at": "2026-10-13T09:05:01Z",
"payload": {
"id": "5d0c2b7e-8a43-4c4e-9f1e-2f0b9a6c1d33",
"type": "release.approved",
"api_version": "v1",
"occurred_at": "2026-10-13T09:05:00Z",
"account_id": 12,
"data": {
"release": {
"id": 812,
"title": "Midnight Run"
}
}
}
}
}
```
### Fehler
| Status | Wann |
| --- | --- |
| 401 | unauthenticated, invalid_key, key_revoked, key_expired oder test_keys_retired. |
| 403 | insufficient_scope: Dem Schlüssel fehlt der Scope; scope nennt ihn. account_inactive oder api_not_in_plan. |
| 404 | not_found: Existiert nicht oder gehört nicht Ihnen. |
| 409 | endpoint_disabled: Der Endpunkt ist deaktiviert. |
| 429 | rate_limited: Retry-After Sekunden warten. |
Quelle: https://developer.hillsmusic.com/de/reference/webhooks/