# Webhooks
> Endpoints que a HILLS Music chama a cada evento: lançamentos, entregas, DDEX, relatórios, pagamentos, solicitações e Live support. Assinados e reenviados.
Endpoints que a HILLS Music chama a cada evento: lançamentos, entregas, DDEX, relatórios, pagamentos, solicitações e Live support. Assinados e reenviados.
URL base `https://api.hillsmusic.com/v1`. Toda requisição envia uma chave de API: `Authorization: Bearer hm_live_…`.
- Listar os tipos de evento de webhook
- Listar endpoints de webhook
- Criar um endpoint de webhook
- Obter um endpoint de webhook
- Atualizar um endpoint de webhook
- Excluir um endpoint de webhook
- Renovar o segredo de um webhook
- Enviar um evento de teste
- Listar as entregas de um endpoint
- Reenviar uma entrega
## Listar os tipos de evento de webhook
`GET /v1/webhooks/events` · Escopo: `webhooks:read` ou `webhooks:write`
Todos os tipos de evento que um endpoint pode assinar, com o que cada um significa. Os payloads estão documentados em Webhooks nesta referência.
### Exemplo de requisição
```bash
curl "https://api.hillsmusic.com/v1/webhooks/events" \
-H "Authorization: Bearer $HILLS_API_KEY"
```
### Resposta `200`
```json
{
"data": [
{
"type": "release.approved",
"label": "Release approved",
"description": "A release was approved and is queued for its stores."
}
]
}
```
### Erros
| Status | Quando |
| --- | --- |
| 401 | unauthenticated, invalid_key, key_revoked, key_expired ou test_keys_retired. |
| 403 | insufficient_scope: falta à chave o escopo; scope indica qual. account_inactive ou api_not_in_plan. |
| 429 | rate_limited: aguarde Retry-After segundos. |
## Listar endpoints de webhook
`GET /v1/webhooks` · Escopo: `webhooks:read` ou `webhooks:write`
Seus endpoints de webhook (no máximo 20), dos mais antigos para os mais recentes. O segredo nunca é listado.
### Exemplo de requisição
```bash
curl "https://api.hillsmusic.com/v1/webhooks" \
-H "Authorization: Bearer $HILLS_API_KEY"
```
### Resposta `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
}
]
}
```
### Erros
| Status | Quando |
| --- | --- |
| 401 | unauthenticated, invalid_key, key_revoked, key_expired ou test_keys_retired. |
| 403 | insufficient_scope: falta à chave o escopo; scope indica qual. account_inactive ou api_not_in_plan. |
| 429 | rate_limited: aguarde Retry-After segundos. |
## Criar um endpoint de webhook
`POST /v1/webhooks` · Escopo: `webhooks:write`
Registra uma URL https para os eventos que você escolher. A resposta traz o segredo de assinatura, uma única vez. A URL precisa ser pública: endereços privados, locais e de metadados são recusados.
### Corpo da requisição
JSON.
| Campo | Tipo | Obrigatório | Descrição |
| --- | --- | --- | --- |
| `url` | string | Sim | Para onde enviar os eventos via POST: uma URL https:// pública na porta 443. |
| `description` | string | Não | Uma anotação para você, por exemplo o sistema que os recebe. |
| `events` | array | Sim | Os tipos de evento a enviar (ver Webhooks nesta referência). |
| `enabled` | boolean | Não | Padrão true. |
### Exemplo de requisição
```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"]}'
```
### Resposta `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"
}
```
### Erros
| Status | Quando |
| --- | --- |
| 400 | invalid: um parâmetro está errado; field indica qual. invalid_url: não é uma URL https pública na porta 443. |
| 401 | unauthenticated, invalid_key, key_revoked, key_expired ou test_keys_retired. |
| 403 | insufficient_scope: falta à chave o escopo; scope indica qual. account_inactive ou api_not_in_plan. |
| 409 | too_many: já existem 20 endpoints. |
| 429 | rate_limited: aguarde Retry-After segundos. |
## Obter um endpoint de webhook
`GET /v1/webhooks/{id}` · Escopo: `webhooks:read` ou `webhooks:write`
Um endpoint com a sua saúde: último sucesso e última falha, tentativas falhas seguidas e por que está desativado.
### Parâmetros
| Parâmetro | Em | Tipo | Obrigatório | Descrição |
| --- | --- | --- | --- | --- |
| `id` | path | integer | Sim | O id do endpoint. |
### Exemplo de requisição
```bash
curl "https://api.hillsmusic.com/v1/webhooks/7" \
-H "Authorization: Bearer $HILLS_API_KEY"
```
### Resposta `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
}
}
```
### Erros
| Status | Quando |
| --- | --- |
| 401 | unauthenticated, invalid_key, key_revoked, key_expired ou test_keys_retired. |
| 403 | insufficient_scope: falta à chave o escopo; scope indica qual. account_inactive ou api_not_in_plan. |
| 404 | not_found: não existe, ou não é seu. |
| 429 | rate_limited: aguarde Retry-After segundos. |
## Atualizar um endpoint de webhook
`PATCH /v1/webhooks/{id}` · Escopo: `webhooks:write`
Altera a URL, a descrição, os eventos, ou desativa e reativa o endpoint (enabled). Reativá-lo zera a contagem de falhas; as entregas abandonadas enquanto ele estava desativado podem ser reenviadas com retry.
### Parâmetros
| Parâmetro | Em | Tipo | Obrigatório | Descrição |
| --- | --- | --- | --- | --- |
| `id` | path | integer | Sim | O id do endpoint. |
### Corpo da requisição
JSON.
| Campo | Tipo | Obrigatório | Descrição |
| --- | --- | --- | --- |
| `url` | string | Não | Para onde enviar os eventos via POST: uma URL https:// pública na porta 443. |
| `description` | string | Não | Uma anotação para você, por exemplo o sistema que os recebe. |
| `events` | array | Não | Os tipos de evento a enviar (ver Webhooks nesta referência). |
| `enabled` | boolean | Não | false desativa; true reativa. |
### Exemplo de requisição
```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}'
```
### Resposta `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
}
}
```
### Erros
| Status | Quando |
| --- | --- |
| 400 | invalid: um parâmetro está errado; field indica qual. invalid_url: não é uma URL https pública na porta 443. |
| 401 | unauthenticated, invalid_key, key_revoked, key_expired ou test_keys_retired. |
| 403 | insufficient_scope: falta à chave o escopo; scope indica qual. account_inactive ou api_not_in_plan. |
| 404 | not_found: não existe, ou não é seu. |
| 429 | rate_limited: aguarde Retry-After segundos. |
## Excluir um endpoint de webhook
`DELETE /v1/webhooks/{id}` · Escopo: `webhooks:write`
Exclui o endpoint e o seu log de entregas. Nada mais é enviado a ele.
### Parâmetros
| Parâmetro | Em | Tipo | Obrigatório | Descrição |
| --- | --- | --- | --- | --- |
| `id` | path | integer | Sim | O id do endpoint. |
### Exemplo de requisição
```bash
curl -X DELETE "https://api.hillsmusic.com/v1/webhooks/7" \
-H "Authorization: Bearer $HILLS_API_KEY"
```
### Resposta `200`
```json
{
"ok": true
}
```
### Erros
| Status | Quando |
| --- | --- |
| 401 | unauthenticated, invalid_key, key_revoked, key_expired ou test_keys_retired. |
| 403 | insufficient_scope: falta à chave o escopo; scope indica qual. account_inactive ou api_not_in_plan. |
| 404 | not_found: não existe, ou não é seu. |
| 429 | rate_limited: aguarde Retry-After segundos. |
## Renovar o segredo de um webhook
`POST /v1/webhooks/{id}/roll-secret` · Escopo: `webhooks:write`
Gera um novo segredo de assinatura; o antigo para de funcionar na hora. O novo segredo aparece só nesta resposta.
### Parâmetros
| Parâmetro | Em | Tipo | Obrigatório | Descrição |
| --- | --- | --- | --- | --- |
| `id` | path | integer | Sim | O id do endpoint. |
### Exemplo de requisição
```bash
curl -X POST "https://api.hillsmusic.com/v1/webhooks/7/roll-secret" \
-H "Authorization: Bearer $HILLS_API_KEY"
```
### Resposta `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"
}
```
### Erros
| Status | Quando |
| --- | --- |
| 401 | unauthenticated, invalid_key, key_revoked, key_expired ou test_keys_retired. |
| 403 | insufficient_scope: falta à chave o escopo; scope indica qual. account_inactive ou api_not_in_plan. |
| 404 | not_found: não existe, ou não é seu. |
| 429 | rate_limited: aguarde Retry-After segundos. |
## Enviar um evento de teste
`POST /v1/webhooks/{id}/test` · Escopo: `webhooks:write`
Coloca na fila um evento webhook.test para este endpoint, quaisquer que sejam os eventos dele, assinado como qualquer outro. O resultado aparece nas entregas.
### Parâmetros
| Parâmetro | Em | Tipo | Obrigatório | Descrição |
| --- | --- | --- | --- | --- |
| `id` | path | integer | Sim | O id do endpoint. |
### Exemplo de requisição
```bash
curl -X POST "https://api.hillsmusic.com/v1/webhooks/7/test" \
-H "Authorization: Bearer $HILLS_API_KEY"
```
### Resposta `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"
}
}
}
}
}
```
### Erros
| Status | Quando |
| --- | --- |
| 401 | unauthenticated, invalid_key, key_revoked, key_expired ou test_keys_retired. |
| 403 | insufficient_scope: falta à chave o escopo; scope indica qual. account_inactive ou api_not_in_plan. |
| 404 | not_found: não existe, ou não é seu. |
| 409 | endpoint_disabled: o endpoint está desativado. |
| 429 | rate_limited: aguarde Retry-After segundos. |
## Listar as entregas de um endpoint
`GET /v1/webhooks/{id}/deliveries` · Escopo: `webhooks:read` ou `webhooks:write`
O que foi enviado ao endpoint nos últimos 30 dias, das mais recentes para as mais antigas: o payload, as tentativas, o último status HTTP e horário, e o erro.
### Parâmetros
| Parâmetro | Em | Tipo | Obrigatório | Descrição |
| --- | --- | --- | --- | --- |
| `id` | path | integer | Sim | O id do endpoint. |
| `status` | query | `pending` \| `succeeded` \| `failed` | Não | Apenas estas. |
| `event` | query | string | Não | Apenas este tipo de evento. |
| `limit` | query | number | Não | 1–100, padrão 50. |
| `before` | query | number | Não | Entregas anteriores a este id de entrega (a próxima página). |
### Exemplo de requisição
```bash
curl "https://api.hillsmusic.com/v1/webhooks/7/deliveries?status=failed" \
-H "Authorization: Bearer $HILLS_API_KEY"
```
### Resposta `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
}
```
### Erros
| Status | Quando |
| --- | --- |
| 400 | invalid: um parâmetro está errado; field indica qual. |
| 401 | unauthenticated, invalid_key, key_revoked, key_expired ou test_keys_retired. |
| 403 | insufficient_scope: falta à chave o escopo; scope indica qual. account_inactive ou api_not_in_plan. |
| 404 | not_found: não existe, ou não é seu. |
| 429 | rate_limited: aguarde Retry-After segundos. |
## Reenviar uma entrega
`POST /v1/webhooks/{id}/deliveries/{delivery_id}/retry` · Escopo: `webhooks:write`
Envia o mesmo evento (mesmo id e payload) ao endpoint de novo, agora.
### Parâmetros
| Parâmetro | Em | Tipo | Obrigatório | Descrição |
| --- | --- | --- | --- | --- |
| `id` | path | integer | Sim | O id do endpoint. |
| `delivery_id` | path | integer | Sim | O id da entrega. |
### Exemplo de requisição
```bash
curl -X POST "https://api.hillsmusic.com/v1/webhooks/7/deliveries/1042/retry" \
-H "Authorization: Bearer $HILLS_API_KEY"
```
### Resposta `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"
}
}
}
}
}
```
### Erros
| Status | Quando |
| --- | --- |
| 401 | unauthenticated, invalid_key, key_revoked, key_expired ou test_keys_retired. |
| 403 | insufficient_scope: falta à chave o escopo; scope indica qual. account_inactive ou api_not_in_plan. |
| 404 | not_found: não existe, ou não é seu. |
| 409 | endpoint_disabled: o endpoint está desativado. |
| 429 | rate_limited: aguarde Retry-After segundos. |
Fonte: https://developer.hillsmusic.com/pt/reference/webhooks/