# Webhooks

> Suscríbase a eventos y gestione las entregas de webhooks

Source: https://docs.graph8.com/es/developers/webhooks/

> **Tip: ¿Usa el SDK?**
> El [SDK de JavaScript](https://docs.graph8.com/developers/sdk/#webhooks) ofrece `g8.webhooks.on(event, callback)` para escuchar eventos mediante programación.

Los webhooks le permiten recibir callbacks HTTP en tiempo real cuando ocurren eventos en su organización. Puede suscribirse a tipos de eventos específicos y graph8 enviará un payload JSON firmado mediante POST a su endpoint.

---

## Eventos disponibles

`GET /webhooks/events`

Devuelve todos los tipos de eventos a los que puede suscribirse.

### Ejemplo

**cURL**

```bash
curl "https://api.graph8.com/api/v1/webhooks/events" \
  -H "Authorization: Bearer $API_KEY"
```

### Respuesta

```json
{
  "data": [
    { "event": "campaign.created" },
    { "event": "campaign.updated" },
    { "event": "campaign.deleted" },
    { "event": "campaign.launched" },
    { "event": "campaign.status_changed" },
    { "event": "document.created" },
    { "event": "document.updated" },
    { "event": "document.generated" },
    { "event": "intelligence.completed" },
    { "event": "research.completed" },
    { "event": "company.enriched" },
    { "event": "person.enriched" },
    { "event": "company_intelligence.completed" }
  ]
}
```

---

## Listar webhooks

`GET /webhooks`

Devuelve todas las suscripciones de webhook de su organización.

### Parámetros de consulta

| Parámetro | Tipo | Predeterminado | Descripción |
|-----------|------|----------------|-------------|
| `is_active` | boolean | — | Filtrar por estado activo |

### Ejemplo

**cURL**

```bash
curl "https://api.graph8.com/api/v1/webhooks" \
  -H "Authorization: Bearer $API_KEY"
```

**Python**

```python
response = requests.get(
    f"{BASE_URL}/webhooks",
    headers=HEADERS
)
```

### Respuesta

```json
{
  "data": [
    {
      "id": "wh-abc",
      "name": "CRM Sync",
      "url": "https://example.com/webhooks/graph8",
      "events": ["campaign.created", "campaign.updated"],
      "is_active": true,
      "created_at": "2026-02-20T10:00:00",
      "updated_at": "2026-02-20T10:00:00"
    }
  ]
}
```

---

## Crear webhook

`POST /webhooks`

Crea una nueva suscripción de webhook. El `secret` de firma se devuelve una sola vez en la respuesta; guárdelo de forma segura.

Máximo 10 webhooks activos por organización.

Devuelve `201 Created`.

### Cuerpo de la solicitud

| Campo | Tipo | Requerido | Descripción |
|-------|------|-----------|-------------|
| `url` | string | Sí | URL de destino para la entrega |
| `events` | string[] | Sí | Tipos de eventos a los que suscribirse |
| `name` | string | No | Nombre legible |

### Ejemplo

**cURL**

```bash
curl -X POST "https://api.graph8.com/api/v1/webhooks" \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://example.com/webhooks/graph8",
    "events": ["campaign.created", "campaign.launched"],
    "name": "CRM Sync"
  }'
```

**Python**

```python
response = requests.post(
    f"{BASE_URL}/webhooks",
    headers=HEADERS,
    json={
        "url": "https://example.com/webhooks/graph8",
        "events": ["campaign.created", "campaign.launched"],
        "name": "CRM Sync"
    }
)
secret = response.json()["data"]["secret"]  # Store this!
```

### Respuesta

```json
{
  "data": {
    "id": "wh-abc",
    "name": "CRM Sync",
    "url": "https://example.com/webhooks/graph8",
    "events": ["campaign.created", "campaign.launched"],
    "is_active": true,
    "secret": "whsec_a1b2c3d4e5f6..."
  }
}
```

### Verificación de firmas

Cada entrega incluye un encabezado `X-Webhook-Signature`. Verifíquelo con HMAC-SHA256:

```python
import hashlib, hmac

def verify_signature(payload: bytes, signature: str, secret: str) -> bool:
    expected = hmac.new(
        secret.encode(), payload, hashlib.sha256
    ).hexdigest()
    return hmac.compare_digest(expected, signature)
```

---

## Obtener webhook

`GET /webhooks/{webhook_id}`

Devuelve los detalles del webhook. El `secret` **no** se incluye en la respuesta.

---

## Actualizar webhook

`PATCH /webhooks/{webhook_id}`

Actualización parcial: envíe solo los campos que desea modificar.

### Cuerpo de la solicitud

| Campo | Tipo | Descripción |
|-------|------|-------------|
| `url` | string | URL de destino |
| `events` | string[] | Tipos de eventos |
| `name` | string | Nombre legible |
| `is_active` | boolean | Activar o desactivar |

---

## Eliminar webhook

`DELETE /webhooks/{webhook_id}`

Devuelve `204 No Content` cuando se completa con éxito.

---

## Listar entregas

`GET /webhooks/{webhook_id}/deliveries`

Devuelve los intentos de entrega de un webhook, con paginación.

### Parámetros de consulta

| Parámetro | Tipo | Predeterminado | Descripción |
|-----------|------|----------------|-------------|
| `page` | integer | 1 | Número de página |
| `limit` | integer | 50 | Elementos por página (máx. 200) |
| `status` | string | — | Filtrar por estado de entrega (`success`, `failed`, `pending`) |

### Ejemplo

**cURL**

```bash
curl "https://api.graph8.com/api/v1/webhooks/wh-abc/deliveries" \
  -H "Authorization: Bearer $API_KEY"
```

### Respuesta

```json
{
  "data": [
    {
      "id": "del-1",
      "event": "campaign.created",
      "status": "success",
      "attempts": 1,
      "max_attempts": 3,
      "response_code": 200,
      "error_message": null,
      "created_at": "2026-02-25T10:00:00",
      "completed_at": "2026-02-25T10:00:01"
    }
  ],
  "pagination": {
    "page": 1,
    "limit": 50,
    "total": 1,
    "has_next": false
  }
}
```

Las entregas fallidas se reintentan hasta 3 veces con intervalos crecientes (10s, 60s, 300s).
