# Webhooks > Les endpoints appelés par HILLS Music à chaque événement : sorties, livraisons, DDEX, relevés, versements, demandes et support en direct. Signés, relancés. Les endpoints appelés par HILLS Music à chaque événement : sorties, livraisons, DDEX, relevés, versements, demandes et support en direct. Signés, relancés. URL de base `https://api.hillsmusic.com/v1`. Chaque requête envoie une clé d’API : `Authorization: Bearer hm_live_…`. - Lister les types d’événements webhook - Lister les endpoints webhook - Créer un endpoint webhook - Obtenir un endpoint webhook - Modifier un endpoint webhook - Supprimer un endpoint webhook - Renouveler le secret d’un webhook - Envoyer un événement de test - Lister les livraisons d’un endpoint - Relancer une livraison ## Lister les types d’événements webhook `GET /v1/webhooks/events` · Scope : `webhooks:read` ou `webhooks:write` Tous les types d’événements auxquels un endpoint peut s’abonner, avec leur signification. Les payloads sont documentés sous webhooks dans cette référence. ### Exemple de requête ```bash curl "https://api.hillsmusic.com/v1/webhooks/events" \ -H "Authorization: Bearer $HILLS_API_KEY" ``` ### Réponse `200` ```json { "data": [ { "type": "release.approved", "label": "Release approved", "description": "A release was approved and is queued for its stores." } ] } ``` ### Erreurs | Statut | Quand | | --- | --- | | 401 | unauthenticated, invalid_key, key_revoked, key_expired ou test_keys_retired. | | 403 | insufficient_scope : la clé n’a pas le scope requis ; scope l’indique. account_inactive ou api_not_in_plan. | | 429 | rate_limited : attendez le nombre de secondes indiqué par Retry-After. | ## Lister les endpoints webhook `GET /v1/webhooks` · Scope : `webhooks:read` ou `webhooks:write` Vos endpoints webhook (20 au maximum), du plus ancien au plus récent. Le secret n’est jamais listé. ### Exemple de requête ```bash curl "https://api.hillsmusic.com/v1/webhooks" \ -H "Authorization: Bearer $HILLS_API_KEY" ``` ### Réponse `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 } ] } ``` ### Erreurs | Statut | Quand | | --- | --- | | 401 | unauthenticated, invalid_key, key_revoked, key_expired ou test_keys_retired. | | 403 | insufficient_scope : la clé n’a pas le scope requis ; scope l’indique. account_inactive ou api_not_in_plan. | | 429 | rate_limited : attendez le nombre de secondes indiqué par Retry-After. | ## Créer un endpoint webhook `POST /v1/webhooks` · Scope : `webhooks:write` Enregistre une URL https pour les événements choisis. La réponse contient le secret de signature, une seule fois. L’URL doit être publique : les adresses privées, locales et de métadonnées sont refusées. ### Corps de la requête JSON. | Champ | Type | Obligatoire | Description | | --- | --- | --- | --- | | `url` | string | Oui | Où envoyer les événements en POST : une URL https:// publique sur le port 443. | | `description` | string | Non | Une note pour vous, par exemple le système qui les reçoit. | | `events` | array | Oui | Les types d’événements à envoyer (voir Webhooks dans cette référence). | | `enabled` | boolean | Non | true par défaut. | ### Exemple de requête ```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"]}' ``` ### Réponse `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" } ``` ### Erreurs | Statut | Quand | | --- | --- | | 400 | invalid : un paramètre est incorrect ; field l’indique. invalid_url : pas une URL https publique sur le port 443. | | 401 | unauthenticated, invalid_key, key_revoked, key_expired ou test_keys_retired. | | 403 | insufficient_scope : la clé n’a pas le scope requis ; scope l’indique. account_inactive ou api_not_in_plan. | | 409 | too_many : il existe déjà 20 endpoints. | | 429 | rate_limited : attendez le nombre de secondes indiqué par Retry-After. | ## Obtenir un endpoint webhook `GET /v1/webhooks/{id}` · Scope : `webhooks:read` ou `webhooks:write` Un endpoint avec son état de santé : dernier succès et dernier échec, tentatives échouées consécutives et raison de sa désactivation. ### Paramètres | Paramètre | Emplacement | Type | Obligatoire | Description | | --- | --- | --- | --- | --- | | `id` | path | integer | Oui | L’identifiant de l’endpoint. | ### Exemple de requête ```bash curl "https://api.hillsmusic.com/v1/webhooks/7" \ -H "Authorization: Bearer $HILLS_API_KEY" ``` ### Réponse `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 } } ``` ### Erreurs | Statut | Quand | | --- | --- | | 401 | unauthenticated, invalid_key, key_revoked, key_expired ou test_keys_retired. | | 403 | insufficient_scope : la clé n’a pas le scope requis ; scope l’indique. account_inactive ou api_not_in_plan. | | 404 | not_found : la ressource n’existe pas ou ne vous appartient pas. | | 429 | rate_limited : attendez le nombre de secondes indiqué par Retry-After. | ## Modifier un endpoint webhook `PATCH /v1/webhooks/{id}` · Scope : `webhooks:write` Modifie son URL, sa description, ses événements, ou le désactive et le réactive (enabled). La réactivation remet son compteur d’échecs à zéro ; les livraisons abandonnées pendant sa désactivation peuvent être renvoyées avec retry. ### Paramètres | Paramètre | Emplacement | Type | Obligatoire | Description | | --- | --- | --- | --- | --- | | `id` | path | integer | Oui | L’identifiant de l’endpoint. | ### Corps de la requête JSON. | Champ | Type | Obligatoire | Description | | --- | --- | --- | --- | | `url` | string | Non | Où envoyer les événements en POST : une URL https:// publique sur le port 443. | | `description` | string | Non | Une note pour vous, par exemple le système qui les reçoit. | | `events` | array | Non | Les types d’événements à envoyer (voir Webhooks dans cette référence). | | `enabled` | boolean | Non | false le désactive ; true le réactive. | ### Exemple de requête ```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}' ``` ### Réponse `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 } } ``` ### Erreurs | Statut | Quand | | --- | --- | | 400 | invalid : un paramètre est incorrect ; field l’indique. invalid_url : pas une URL https publique sur le port 443. | | 401 | unauthenticated, invalid_key, key_revoked, key_expired ou test_keys_retired. | | 403 | insufficient_scope : la clé n’a pas le scope requis ; scope l’indique. account_inactive ou api_not_in_plan. | | 404 | not_found : la ressource n’existe pas ou ne vous appartient pas. | | 429 | rate_limited : attendez le nombre de secondes indiqué par Retry-After. | ## Supprimer un endpoint webhook `DELETE /v1/webhooks/{id}` · Scope : `webhooks:write` Supprime l’endpoint et son journal de livraisons. Plus rien ne lui est envoyé. ### Paramètres | Paramètre | Emplacement | Type | Obligatoire | Description | | --- | --- | --- | --- | --- | | `id` | path | integer | Oui | L’identifiant de l’endpoint. | ### Exemple de requête ```bash curl -X DELETE "https://api.hillsmusic.com/v1/webhooks/7" \ -H "Authorization: Bearer $HILLS_API_KEY" ``` ### Réponse `200` ```json { "ok": true } ``` ### Erreurs | Statut | Quand | | --- | --- | | 401 | unauthenticated, invalid_key, key_revoked, key_expired ou test_keys_retired. | | 403 | insufficient_scope : la clé n’a pas le scope requis ; scope l’indique. account_inactive ou api_not_in_plan. | | 404 | not_found : la ressource n’existe pas ou ne vous appartient pas. | | 429 | rate_limited : attendez le nombre de secondes indiqué par Retry-After. | ## Renouveler le secret d’un webhook `POST /v1/webhooks/{id}/roll-secret` · Scope : `webhooks:write` Génère un nouveau secret de signature ; l’ancien cesse de fonctionner immédiatement. Le nouveau secret ne figure que dans cette réponse. ### Paramètres | Paramètre | Emplacement | Type | Obligatoire | Description | | --- | --- | --- | --- | --- | | `id` | path | integer | Oui | L’identifiant de l’endpoint. | ### Exemple de requête ```bash curl -X POST "https://api.hillsmusic.com/v1/webhooks/7/roll-secret" \ -H "Authorization: Bearer $HILLS_API_KEY" ``` ### Réponse `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" } ``` ### Erreurs | Statut | Quand | | --- | --- | | 401 | unauthenticated, invalid_key, key_revoked, key_expired ou test_keys_retired. | | 403 | insufficient_scope : la clé n’a pas le scope requis ; scope l’indique. account_inactive ou api_not_in_plan. | | 404 | not_found : la ressource n’existe pas ou ne vous appartient pas. | | 429 | rate_limited : attendez le nombre de secondes indiqué par Retry-After. | ## Envoyer un événement de test `POST /v1/webhooks/{id}/test` · Scope : `webhooks:write` Met en file d’attente un événement webhook.test pour cet endpoint, quels que soient ses événements, signé comme n’importe quel autre. Son résultat apparaît dans les livraisons. ### Paramètres | Paramètre | Emplacement | Type | Obligatoire | Description | | --- | --- | --- | --- | --- | | `id` | path | integer | Oui | L’identifiant de l’endpoint. | ### Exemple de requête ```bash curl -X POST "https://api.hillsmusic.com/v1/webhooks/7/test" \ -H "Authorization: Bearer $HILLS_API_KEY" ``` ### Réponse `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" } } } } } ``` ### Erreurs | Statut | Quand | | --- | --- | | 401 | unauthenticated, invalid_key, key_revoked, key_expired ou test_keys_retired. | | 403 | insufficient_scope : la clé n’a pas le scope requis ; scope l’indique. account_inactive ou api_not_in_plan. | | 404 | not_found : la ressource n’existe pas ou ne vous appartient pas. | | 409 | endpoint_disabled : l’endpoint est désactivé. | | 429 | rate_limited : attendez le nombre de secondes indiqué par Retry-After. | ## Lister les livraisons d’un endpoint `GET /v1/webhooks/{id}/deliveries` · Scope : `webhooks:read` ou `webhooks:write` Ce qui a été envoyé à l’endpoint au cours des 30 derniers jours, du plus récent au plus ancien : le payload, les tentatives, le dernier statut HTTP et son heure, et l’erreur. ### Paramètres | Paramètre | Emplacement | Type | Obligatoire | Description | | --- | --- | --- | --- | --- | | `id` | path | integer | Oui | L’identifiant de l’endpoint. | | `status` | query | `pending` \| `succeeded` \| `failed` | Non | Uniquement celles-ci. | | `event` | query | string | Non | Uniquement ce type d’événement. | | `limit` | query | number | Non | 1–100, 50 par défaut. | | `before` | query | number | Non | Les livraisons antérieures à cet identifiant de livraison (la page suivante). | ### Exemple de requête ```bash curl "https://api.hillsmusic.com/v1/webhooks/7/deliveries?status=failed" \ -H "Authorization: Bearer $HILLS_API_KEY" ``` ### Réponse `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 } ``` ### Erreurs | Statut | Quand | | --- | --- | | 400 | invalid : un paramètre est incorrect ; field l’indique. | | 401 | unauthenticated, invalid_key, key_revoked, key_expired ou test_keys_retired. | | 403 | insufficient_scope : la clé n’a pas le scope requis ; scope l’indique. account_inactive ou api_not_in_plan. | | 404 | not_found : la ressource n’existe pas ou ne vous appartient pas. | | 429 | rate_limited : attendez le nombre de secondes indiqué par Retry-After. | ## Relancer une livraison `POST /v1/webhooks/{id}/deliveries/{delivery_id}/retry` · Scope : `webhooks:write` Renvoie immédiatement le même événement (même id et même payload) à l’endpoint. ### Paramètres | Paramètre | Emplacement | Type | Obligatoire | Description | | --- | --- | --- | --- | --- | | `id` | path | integer | Oui | L’identifiant de l’endpoint. | | `delivery_id` | path | integer | Oui | L’identifiant de la livraison. | ### Exemple de requête ```bash curl -X POST "https://api.hillsmusic.com/v1/webhooks/7/deliveries/1042/retry" \ -H "Authorization: Bearer $HILLS_API_KEY" ``` ### Réponse `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" } } } } } ``` ### Erreurs | Statut | Quand | | --- | --- | | 401 | unauthenticated, invalid_key, key_revoked, key_expired ou test_keys_retired. | | 403 | insufficient_scope : la clé n’a pas le scope requis ; scope l’indique. account_inactive ou api_not_in_plan. | | 404 | not_found : la ressource n’existe pas ou ne vous appartient pas. | | 409 | endpoint_disabled : l’endpoint est désactivé. | | 429 | rate_limited : attendez le nombre de secondes indiqué par Retry-After. | Source: https://developer.hillsmusic.com/fr/reference/webhooks/