# Webhook API

> Registra endpoint che ricevono notifiche firmate degli eventi.

URL di base: `https://api.emailit.com/v2`. Autenticati con `Authorization: Bearer <API key>`.

## Crea un webhook — POST /webhooks

> Registra un endpoint HTTP che riceve notifiche firmate degli eventi, scegli i suoi tipi di evento e, da Pro in su, un filtro sul payload.

# Crea un webhook

Crea un endpoint webhook nel workspace. Emailit invia gli eventi corrispondenti all’URL in batch fino a 100, come array JSON firmato con il `secret` del webhook. Per il formato delle richieste, vedi [Richieste webhook](/it/docs/webhooks/webhook-requests/). Richiede una chiave API con il permesso `full`.

`POST /webhooks`

## Corpo della richiesta

- `name` (string, obbligatorio): Nome del webhook. Deve essere univoco nel workspace; puoi usarlo al posto dell’ID negli altri endpoint dei webhook.

- `url` (string, obbligatorio): Endpoint che riceve gli eventi. Sono accettati URL `http` e `https`; in produzione usa `https`. Emailit risolve il nome host al salvataggio e rifiuta `localhost`, gli indirizzi IP privati, link-local e gli altri indirizzi riservati. Durante la consegna i reindirizzamenti non vengono seguiti, quindi usa l’URL finale.

- `all_events` (boolean): Invia tutti i tipi di evento, compresi quelli aggiunti in futuro. Il valore predefinito è `false`. Quando è `true`, `events` viene ignorato.

- `enabled` (boolean): Indica se Emailit consegna gli eventi al webhook. Il valore predefinito è `true`.

- `events` (string[]): Tipi di evento da inviare, ad esempio `["email.delivered", "email.bounced"]`. Vedi [Tipi di evento](/it/docs/webhooks/event-types/). Il valore predefinito è `[]`, che con `all_events: false` significa che il webhook non riceve nulla. I nomi degli eventi non vengono convalidati. Un tipo scritto male viene salvato ma non corrisponde mai a nessun evento.

- `filter` (object | null): Filtro sul payload. Emailit invia solo gli eventi il cui oggetto corrisponde alle regole. Disponibile nei piani Pro, Business e Custom; con Pay as you go un filtro con regole restituisce `403`.

- `filter.match` (string): `all` (predefinito) invia un evento quando corrispondono tutte le regole. `any` lo invia quando corrisponde almeno una regola.

- `filter.rules` (object[]): Fino a 25 regole.

- `filter.rules[].field` (string, obbligatorio): Percorso con punti all’interno dell’oggetto dell’evento, ad esempio `to`, `status`, `meta.plan` o, per gli eventi di clic e apertura, `email.campaign.id`. Un prefisso `payload.` iniziale viene ignorato.

- `filter.rules[].operator` (string, obbligatorio): `equals`, `not_equals`, `contains`, `not_contains`, `starts_with`, `ends_with`, `greater_than`, `less_than`, `is_set`, `is_not_set`, `in` o `not_in`. Gli operatori di testo confrontano i valori come stringhe; `greater_than` e `less_than` confrontano numeri.

- `filter.rules[].value` (any): Valore con cui confrontare. Obbligatorio per tutti gli operatori tranne `is_set` e `is_not_set`. Con `in` e `not_in` usa un array.

## Restituisce

Restituisce `201 Created` con l’oggetto webhook, compreso il `secret` di firma (`whsec_` seguito da 64 caratteri esadecimali). Usa il secret per [verificare le firme delle richieste](/it/docs/webhooks/request-signature/). Puoi leggerlo di nuovo con [Recupera un webhook](/it/docs/api-reference/webhooks/get/) e ruotarlo con [Ruota il secret di firma](/it/docs/api-reference/webhooks/reset-secret/).

| Stato | Quando |
| --- | --- |
| `400` | Manca `name` o `url`, l’URL non è valido, non può essere risolto o punta a un indirizzo bloccato, oppure il filtro non è valido. |
| `403` | Il filtro ha delle regole e il piano non include i filtri dei webhook. Il corpo è `{"error": "plan_required", "required_plan": "pro"}`. |
| `409` | Esiste già un webhook con questo nome. Il corpo include `id` e `name` del webhook esistente in `existing`. |
| `422` | Il workspace ha raggiunto il limite di webhook del piano. Il corpo include `usage.used` e `usage.limit`. Vedi [Limiti e quote](/it/docs/limits/). |

**Richiesta** `POST /webhooks`

**Node.js**

```javascript
import { Emailit } from '@emailit/node';
const emailit = new Emailit('your_api_key');

const webhook = await emailit.webhooks.create({
    name: 'Production events',
    url: 'https://api.acme.com/webhooks/emailit',
    events: ['email.delivered']
});
```

**Python**

```python
from emailit import EmailitClient
client = EmailitClient("your_api_key")

webhook = client.webhooks.create({
    "name": "Production events",
    "url": "https://api.acme.com/webhooks/emailit",
    "events": ["email.delivered"]
})
```

**PHP**

```php
$emailit = Emailit::client('your_api_key');

$webhook = $emailit->webhooks()->create([
    'name' => 'Production events',
    'url' => 'https://api.acme.com/webhooks/emailit',
    'events' => ['email.delivered']
]);
```

**Ruby**

```ruby
require "emailit"
client = Emailit::EmailitClient.new("your_api_key")

webhook = client.webhooks.create(
    name: "Production events",
    url: "https://api.acme.com/webhooks/emailit",
    events: ["email.delivered"]
)
```

**Go**

```go
import "github.com/emailit/emailit-go/v2"
client := emailit.NewClient("your_api_key")

webhook, err := client.Webhooks.Create(&emailit.CreateWebhookRequest{
    Name:   "Production events",
    Url:    "https://api.acme.com/webhooks/emailit",
    Events: []string{"email.delivered"},
})
```

**Rust**

```rust
use emailit::Emailit;
let emailit = Emailit::new("your_api_key");

let webhook = emailit.webhooks.create(
    emailit::types::CreateWebhookParams::new(
        "Production events",
        "https://api.acme.com/webhooks/emailit"
    ).with_events(vec!["email.delivered".into()])
).await?;
```

**Java**

```java
import com.emailit.*;
import com.emailit.params.*;
EmailitClient emailit = new EmailitClient("your_api_key");

EmailitObject webhook = emailit.webhooks().create(
    WebhookCreateParams.builder()
        .setName("Production events")
        .setUrl("https://api.acme.com/webhooks/emailit")
        .setEvents(Arrays.asList("email.delivered"))
        .build()
);
```

**.NET**

```csharp
using Emailit;
var emailit = new EmailitClient("your_api_key");

var webhook = emailit.Webhooks.Create(new WebhookCreateOptions {
    Name = "Production events",
    Url = "https://api.acme.com/webhooks/emailit",
    Events = new[] { "email.delivered" }
});
```

**Laravel**

```php
use Emailit\Laravel\Facades\Emailit;

$webhook = Emailit::webhooks()->create([
    'name' => 'Production events',
    'url' => 'https://api.acme.com/webhooks/emailit',
    'events' => ['email.delivered']
]);
```

**cURL**

```bash
curl -X POST https://api.emailit.com/v2/webhooks \
  -H "Authorization: Bearer your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Production events",
    "url": "https://api.acme.com/webhooks/emailit",
    "events": ["email.delivered"]
  }'
```

**201**

```json
{
  "object": "webhook",
  "id": "wh_2xLb3Kp9Qr1Vt7Mn5Ws0Yd4Hc8e",
  "name": "Production events",
  "url": "https://api.acme.com/webhooks/emailit",
  "all_events": false,
  "enabled": true,
  "events": ["email.delivered", "email.bounced"],
  "filter": null,
  "filters_allowed": true,
  "last_used_at": null,
  "created_at": "2026-10-01T09:41:05.302000+00:00",
  "updated_at": "2026-10-01T09:41:05.302000+00:00",
  "secret": "whsec_175a02aca3fb7dc3107ca21e4224a73d058cacc628356a39e020422aec3ca434"
}
```

**400**

```json
{
  "error": "URL resolves to a private/reserved IP address"
}
```

**403**

```json
{
  "error": "plan_required",
  "required_plan": "pro"
}
```

**409**

```json
{
  "error": "Webhook with this name already exists",
  "existing": {
    "object": "webhook",
    "id": "wh_2xLb3Kp9Qr1Vt7Mn5Ws0Yd4Hc8e",
    "name": "Production events"
  }
}
```

**422**

```json
{
  "error": "Pay as you go includes 3 webhook endpoints.",
  "usage": {
    "used": 3,
    "limit": 3
  }
}
```

**Filtro**

```json
{
  "name": "Enterprise bounces",
  "url": "https://api.acme.com/webhooks/emailit",
  "events": ["email.bounced", "email.complained"],
  "filter": {
    "match": "all",
    "rules": [
      { "field": "meta.plan", "operator": "equals", "value": "enterprise" },
      { "field": "to", "operator": "not_contains", "value": "@acme.com" }
    ]
  }
}
```

---
Fonte: https://emailit.com/it/docs/api-reference/webhooks/create/

## Recupera un webhook — GET /webhooks/{id}

> Recupera un webhook tramite il suo ID o nome, con URL, tipi di evento, filtro sul payload e secret di firma.

# Recupera un webhook

Restituisce un webhook, cercato per ID o per nome. È l’unico endpoint di lettura che restituisce il `secret` di firma. Richiede una chiave API con il permesso `full`.

`GET /webhooks/:id`

## Parametri di percorso

- `id` (string, obbligatorio): ID del webhook (`wh_…`) o nome del webhook, codificato per l’URL.

## Restituisce

Restituisce `200 OK` con l’oggetto webhook, compresi `secret` e `filters_allowed` (indica se il piano consente al webhook di usare un filtro sul payload). `last_used_at` è il momento dell’ultima consegna riuscita, oppure `null` se non è stato ancora consegnato nulla.

Restituisce `404` con `error: "Webhook not found"` se nessun webhook corrisponde.

**Richiesta** `GET /webhooks/{id}`

**Node.js**

```javascript
import { Emailit } from '@emailit/node';
const emailit = new Emailit('your_api_key');

const webhook = await emailit.webhooks.get('wh_2xLb3Kp9Qr1Vt7Mn5Ws0Yd4Hc8e');
```

**Python**

```python
from emailit import EmailitClient
client = EmailitClient("your_api_key")

webhook = client.webhooks.get("wh_2xLb3Kp9Qr1Vt7Mn5Ws0Yd4Hc8e")
```

**PHP**

```php
$emailit = Emailit::client('your_api_key');

$webhook = $emailit->webhooks()->get('wh_2xLb3Kp9Qr1Vt7Mn5Ws0Yd4Hc8e');
```

**Ruby**

```ruby
require "emailit"
client = Emailit::EmailitClient.new("your_api_key")

webhook = client.webhooks.get("wh_2xLb3Kp9Qr1Vt7Mn5Ws0Yd4Hc8e")
```

**Go**

```go
import "github.com/emailit/emailit-go/v2"
client := emailit.NewClient("your_api_key")

webhook, err := client.Webhooks.Get("wh_2xLb3Kp9Qr1Vt7Mn5Ws0Yd4Hc8e")
```

**Rust**

```rust
use emailit::Emailit;
let emailit = Emailit::new("your_api_key");

let webhook = emailit.webhooks.get("wh_2xLb3Kp9Qr1Vt7Mn5Ws0Yd4Hc8e").await?;
```

**Java**

```java
import com.emailit.*;
EmailitClient emailit = new EmailitClient("your_api_key");

EmailitObject webhook = emailit.webhooks().get("wh_2xLb3Kp9Qr1Vt7Mn5Ws0Yd4Hc8e");
```

**.NET**

```csharp
using Emailit;
var emailit = new EmailitClient("your_api_key");

var webhook = emailit.Webhooks.Get("wh_2xLb3Kp9Qr1Vt7Mn5Ws0Yd4Hc8e");
```

**Laravel**

```php
use Emailit\Laravel\Facades\Emailit;

$webhook = Emailit::webhooks()->get('wh_2xLb3Kp9Qr1Vt7Mn5Ws0Yd4Hc8e');
```

**cURL**

```bash
curl https://api.emailit.com/v2/webhooks/wh_2xLb3Kp9Qr1Vt7Mn5Ws0Yd4Hc8e \
  -H "Authorization: Bearer your_api_key"
```

**200**

```json
{
  "object": "webhook",
  "id": "wh_2xLb3Kp9Qr1Vt7Mn5Ws0Yd4Hc8e",
  "name": "Production events",
  "url": "https://api.acme.com/webhooks/emailit",
  "all_events": false,
  "enabled": true,
  "events": ["email.delivered", "email.bounced"],
  "filter": {
    "match": "all",
    "rules": [
      { "field": "meta.plan", "operator": "equals", "value": "enterprise" }
    ]
  },
  "filters_allowed": true,
  "last_used_at": "2026-10-01T10:02:17.845000+00:00",
  "created_at": "2026-10-01T09:41:05.302000+00:00",
  "updated_at": "2026-10-01T09:41:05.302000+00:00",
  "secret": "whsec_175a02aca3fb7dc3107ca21e4224a73d058cacc628356a39e020422aec3ca434"
}
```

**404**

```json
{
  "error": "Webhook not found"
}
```

---
Fonte: https://emailit.com/it/docs/api-reference/webhooks/get/

## Aggiorna un webhook — POST /webhooks/{id}

> Modifica il nome, l’URL, i tipi di evento, il filtro sul payload o lo stato di attivazione di un webhook, cercato tramite il suo ID o il suo nome.

# Aggiorna un webhook

Aggiorna un webhook. Invia solo i campi che vuoi modificare; ne serve almeno uno. Il secret di firma non cambia; per ruotarlo usa [Ruota il secret di firma](/it/docs/api-reference/webhooks/reset-secret/). Richiede una chiave API con il permesso `full`.

`POST /webhooks/:id`

## Parametri di percorso

- `id` (string, obbligatorio): ID del webhook (`wh_…`) o nome del webhook, codificato per l’URL.

## Corpo della richiesta

- `name` (string): Nuovo nome. Deve essere univoco nel workspace.

- `url` (string): Nuovo URL dell’endpoint, `http` o `https`. Viene convalidato come in [creazione](/it/docs/api-reference/webhooks/create/).

- `all_events` (boolean): `true` invia tutti i tipi di evento e svuota l’elenco `events`. Se lo imposti su `false`, invia anche `events`, altrimenti il webhook non riceve nulla.

- `enabled` (boolean): `false` interrompe le consegne e `true` le riprende. Gli eventi che si verificano mentre il webhook è disattivato non vengono messi in coda per il webhook e non vengono inviati in seguito.

- `events` (string[]): Sostituisce l’elenco dei tipi di evento. Viene ignorato finché `all_events` è `true`. I nomi non vengono convalidati.

- `filter` (object | null): Sostituisce il filtro sul payload, nello stesso formato usato in [creazione](/it/docs/api-reference/webhooks/create/). Invia `null` per rimuoverlo. Un filtro con regole richiede un piano Pro, Business o Custom.

## Restituisce

Restituisce `200 OK` con il webhook aggiornato. Il `secret` non è incluso; per leggerlo usa [Recupera un webhook](/it/docs/api-reference/webhooks/get/).

| Stato | Quando |
| --- | --- |
| `400` | Il corpo non contiene nessuno dei campi indicati sopra, oppure l’URL o il filtro non sono validi. |
| `403` | Il filtro ha delle regole e il piano non include i filtri dei webhook (`plan_required`). |
| `404` | Nessun webhook corrisponde a `id`. |
| `409` | Un altro webhook usa già il nuovo nome. |

**Richiesta** `POST /webhooks/{id}`

**Node.js**

```javascript
import { Emailit } from '@emailit/node';
const emailit = new Emailit('your_api_key');

const webhook = await emailit.webhooks.update('wh_2xLb3Kp9Qr1Vt7Mn5Ws0Yd4Hc8e', {
    enabled: false
});
```

**Python**

```python
from emailit import EmailitClient
client = EmailitClient("your_api_key")

webhook = client.webhooks.update("wh_2xLb3Kp9Qr1Vt7Mn5Ws0Yd4Hc8e", {
    "enabled": False
})
```

**PHP**

```php
$emailit = Emailit::client('your_api_key');

$webhook = $emailit->webhooks()->update('wh_2xLb3Kp9Qr1Vt7Mn5Ws0Yd4Hc8e', [
    'enabled' => false
]);
```

**Ruby**

```ruby
require "emailit"
client = Emailit::EmailitClient.new("your_api_key")

webhook = client.webhooks.update("wh_2xLb3Kp9Qr1Vt7Mn5Ws0Yd4Hc8e", enabled: false)
```

**Go**

```go
import "github.com/emailit/emailit-go/v2"
client := emailit.NewClient("your_api_key")

webhook, err := client.Webhooks.Update("wh_2xLb3Kp9Qr1Vt7Mn5Ws0Yd4Hc8e", &emailit.UpdateWebhookRequest{
    Enabled: false,
})
```

**Rust**

```rust
use emailit::Emailit;
let emailit = Emailit::new("your_api_key");

let webhook = emailit.webhooks.update("wh_2xLb3Kp9Qr1Vt7Mn5Ws0Yd4Hc8e",
    emailit::types::UpdateWebhookParams {
        enabled: Some(false),
        ..Default::default()
    }
).await?;
```

**Java**

```java
import com.emailit.*;
import com.emailit.params.*;
EmailitClient emailit = new EmailitClient("your_api_key");

EmailitObject webhook = emailit.webhooks().update("wh_2xLb3Kp9Qr1Vt7Mn5Ws0Yd4Hc8e",
    WebhookUpdateParams.builder()
        .setEnabled(false)
        .build()
);
```

**.NET**

```csharp
using Emailit;
var emailit = new EmailitClient("your_api_key");

var webhook = emailit.Webhooks.Update("wh_2xLb3Kp9Qr1Vt7Mn5Ws0Yd4Hc8e", new WebhookUpdateOptions {
    Enabled = false
});
```

**Laravel**

```php
use Emailit\Laravel\Facades\Emailit;

$webhook = Emailit::webhooks()->update('wh_2xLb3Kp9Qr1Vt7Mn5Ws0Yd4Hc8e', [
    'enabled' => false
]);
```

**cURL**

```bash
curl -X POST https://api.emailit.com/v2/webhooks/wh_2xLb3Kp9Qr1Vt7Mn5Ws0Yd4Hc8e \
  -H "Authorization: Bearer your_api_key" \
  -H "Content-Type: application/json" \
  -d '{"enabled": false}'
```

**200**

```json
{
  "object": "webhook",
  "id": "wh_2xLb3Kp9Qr1Vt7Mn5Ws0Yd4Hc8e",
  "name": "Production events",
  "url": "https://api.acme.com/webhooks/emailit",
  "all_events": false,
  "enabled": false,
  "events": ["email.delivered", "email.bounced"],
  "filter": null,
  "filters_allowed": true,
  "last_used_at": "2026-10-01T10:02:17.845000+00:00",
  "created_at": "2026-10-01T09:41:05.302000+00:00",
  "updated_at": "2026-10-01T10:15:40.000000+00:00"
}
```

**400**

```json
{
  "error": "No valid fields provided for update. Provide at least one of: name, url, all_events, enabled, events, filter"
}
```

**404**

```json
{
  "error": "Webhook not found"
}
```

**409**

```json
{
  "error": "Another webhook with this name already exists"
}
```

---
Fonte: https://emailit.com/it/docs/api-reference/webhooks/update/

## Elenca i webhook — GET /webhooks

> Elenca i webhook del workspace con ricerca, filtri e paginazione per pagine, più l’utilizzo dei webhook rispetto al piano.

# Elenca i webhook

Restituisce i webhook del workspace, a partire dal più recente, e quanti ne consente il piano. I secret di firma non sono inclusi nell’elenco. Richiede una chiave API con il permesso `full`.

`GET /webhooks`

## Parametri di query

- `page` (integer): Numero di pagina, a partire da `1`. Il valore predefinito è `1`.

- `limit` (integer): Webhook per pagina, da `1` a `100`. Il valore predefinito è `10`.

- `search` (string): Corrispondenza sul nome o sull’URL del webhook, senza distinzione tra maiuscole e minuscole.

- `match`, `order`, `direction`: vedi [Filtri e ordinamento](https://emailit.com/it/docs/api-reference/filtering/).

## Filtri e ordinamento

Chiavi di filtro e di ordinamento: vedi [Filtri e ordinamento](https://emailit.com/it/docs/api-reference/filtering/).

## Restituisce

Restituisce `200 OK` con i webhook in `data`, `next_page_url` e `previous_page_url` (`null` alle due estremità) e un oggetto `usage`: `used` è il numero di webhook nel workspace, `limit` è il massimo consentito dal piano e `filters_allowed` indica se il piano include i filtri sul payload.

**Richiesta** `GET /webhooks`

**Node.js**

```javascript
import { Emailit } from '@emailit/node';
const emailit = new Emailit('your_api_key');

const webhooks = await emailit.webhooks.list();
```

**Python**

```python
from emailit import EmailitClient
client = EmailitClient("your_api_key")

webhooks = client.webhooks.list()
```

**PHP**

```php
$emailit = Emailit::client('your_api_key');

$webhooks = $emailit->webhooks()->list();
```

**Ruby**

```ruby
require "emailit"
client = Emailit::EmailitClient.new("your_api_key")

webhooks = client.webhooks.list
```

**Go**

```go
import "github.com/emailit/emailit-go/v2"
client := emailit.NewClient("your_api_key")

webhooks, err := client.Webhooks.List(nil)
```

**Rust**

```rust
use emailit::Emailit;
let emailit = Emailit::new("your_api_key");

let webhooks = emailit.webhooks.list(None).await?;
```

**Java**

```java
import com.emailit.*;
EmailitClient emailit = new EmailitClient("your_api_key");

EmailitObject webhooks = emailit.webhooks().list();
```

**.NET**

```csharp
using Emailit;
var emailit = new EmailitClient("your_api_key");

var webhooks = emailit.Webhooks.List();
```

**Laravel**

```php
use Emailit\Laravel\Facades\Emailit;

$webhooks = Emailit::webhooks()->list();
```

**cURL**

```bash
curl https://api.emailit.com/v2/webhooks \
  -H "Authorization: Bearer your_api_key"
```

**200**

```json
{
  "data": [
    {
      "object": "webhook",
      "id": "wh_2xLb3Kp9Qr1Vt7Mn5Ws0Yd4Hc8e",
      "name": "Production events",
      "url": "https://api.acme.com/webhooks/emailit",
      "all_events": false,
      "enabled": true,
      "events": ["email.delivered", "email.bounced"],
      "filter": null,
      "filters_allowed": true,
      "last_used_at": "2026-10-01T10:02:17.845000+00:00",
      "created_at": "2026-10-01T09:41:05.302000+00:00",
      "updated_at": "2026-10-01T10:02:17.845000+00:00"
    }
  ],
  "next_page_url": null,
  "previous_page_url": null,
  "usage": {
    "used": 1,
    "limit": 10,
    "filters_allowed": true
  }
}
```

**401**

```json
{
  "statusCode": 401,
  "error": "Unauthorized",
  "message": "Invalid API key"
}
```

---
Fonte: https://emailit.com/it/docs/api-reference/webhooks/list/

## Elimina un webhook — DELETE /webhooks/{id}

> Elimina un webhook tramite il suo ID o nome. Emailit smette di inviare eventi al suo URL, compresi i nuovi tentativi ancora in sospeso.

# Elimina un webhook

Elimina definitivamente un webhook e le sue iscrizioni agli eventi. Per sospendere temporaneamente le consegne, [aggiorna il webhook](/it/docs/api-reference/webhooks/update/) con `enabled: false`. Richiede una chiave API con il permesso `full`.

`DELETE /webhooks/:id`

## Parametri di percorso

- `id` (string, obbligatorio): ID del webhook (`wh_…`) o nome del webhook, codificato per l’URL.

## Restituisce

Restituisce `200 OK` con `id` e `name` del webhook eliminato e `deleted: true`. Restituisce `404` con `error: "Webhook not found"` se nessun webhook corrisponde.

**Richiesta** `DELETE /webhooks/{id}`

**Node.js**

```javascript
import { Emailit } from '@emailit/node';
const emailit = new Emailit('your_api_key');

await emailit.webhooks.delete('wh_2xLb3Kp9Qr1Vt7Mn5Ws0Yd4Hc8e');
```

**Python**

```python
from emailit import EmailitClient
client = EmailitClient("your_api_key")

client.webhooks.delete("wh_2xLb3Kp9Qr1Vt7Mn5Ws0Yd4Hc8e")
```

**PHP**

```php
$emailit = Emailit::client('your_api_key');

$emailit->webhooks()->delete('wh_2xLb3Kp9Qr1Vt7Mn5Ws0Yd4Hc8e');
```

**Ruby**

```ruby
require "emailit"
client = Emailit::EmailitClient.new("your_api_key")

client.webhooks.delete("wh_2xLb3Kp9Qr1Vt7Mn5Ws0Yd4Hc8e")
```

**Go**

```go
import "github.com/emailit/emailit-go/v2"
client := emailit.NewClient("your_api_key")

err := client.Webhooks.Delete("wh_2xLb3Kp9Qr1Vt7Mn5Ws0Yd4Hc8e")
```

**Rust**

```rust
use emailit::Emailit;
let emailit = Emailit::new("your_api_key");

emailit.webhooks.delete("wh_2xLb3Kp9Qr1Vt7Mn5Ws0Yd4Hc8e").await?;
```

**Java**

```java
import com.emailit.*;
EmailitClient emailit = new EmailitClient("your_api_key");

emailit.webhooks().delete("wh_2xLb3Kp9Qr1Vt7Mn5Ws0Yd4Hc8e");
```

**.NET**

```csharp
using Emailit;
var emailit = new EmailitClient("your_api_key");

emailit.Webhooks.Delete("wh_2xLb3Kp9Qr1Vt7Mn5Ws0Yd4Hc8e");
```

**Laravel**

```php
use Emailit\Laravel\Facades\Emailit;

Emailit::webhooks()->delete('wh_2xLb3Kp9Qr1Vt7Mn5Ws0Yd4Hc8e');
```

**cURL**

```bash
curl -X DELETE https://api.emailit.com/v2/webhooks/wh_2xLb3Kp9Qr1Vt7Mn5Ws0Yd4Hc8e \
  -H "Authorization: Bearer your_api_key"
```

**200**

```json
{
  "object": "webhook",
  "id": "wh_2xLb3Kp9Qr1Vt7Mn5Ws0Yd4Hc8e",
  "name": "Production events",
  "deleted": true
}
```

**404**

```json
{
  "error": "Webhook not found"
}
```

---
Fonte: https://emailit.com/it/docs/api-reference/webhooks/delete/

## Invia un evento di test — POST /webhooks/{id}/test

> Invia un evento di esempio firmato, di qualsiasi tipo, a un endpoint webhook e ricevi subito la risposta dell’endpoint.

# Invia un evento di test

Invia un evento di esempio del tipo che scegli all’URL del webhook e restituisce la risposta del tuo endpoint. Usalo per controllare che l’endpoint sia raggiungibile e verifichi correttamente le [firme](/it/docs/webhooks/request-signature/). Richiede una chiave API con il permesso `full`.

La richiesta ha lo stesso formato, gli stessi header e la stessa firma di una consegna reale: un array JSON con un evento il cui `event_id` inizia con `evt_test_`, firmato con il secret attuale del webhook. Viene inviata anche se il webhook è disattivato o non è iscritto a quel tipo, non viene salvata come richiesta webhook e non viene ritentata. I dati di esempio sono fissi e non si riferiscono a oggetti reali.

Puoi inviare 5 eventi di test al minuto dallo stesso indirizzo IP; oltre questo limite viene restituito `429`.

`POST /webhooks/{id}/test`

## Parametri di percorso

- `id` (string, obbligatorio): L’ID del webhook (`wh_…`) o il nome del webhook.

## Parametri del corpo

- `type` (string, obbligatorio): Il tipo di evento da inviare. Uno dei tipi qui sotto.

| Risorsa | Tipi di evento |
| --- | --- |
| Email | `email.accepted`, `email.scheduled`, `email.delivered`, `email.bounced`, `email.attempted`, `email.failed`, `email.rejected`, `email.clicked`, `email.loaded`, `email.complained`, `email.received`, `email.suppressed`, `email.canceled`, `email.unsubscribed`, `email.resubscribed` |
| Dominio | `domain.created`, `domain.updated`, `domain.deleted` |
| Lista | `audience.created`, `audience.updated`, `audience.deleted` |
| Iscritto | `subscriber.created`, `subscriber.updated`, `subscriber.deleted` |
| Contatto | `contact.created`, `contact.updated`, `contact.deleted` |
| Template | `template.created`, `template.updated`, `template.deleted` |
| Soppressione | `suppression.created`, `suppression.updated`, `suppression.deleted` |
| Verifica email | `email_verification.created`, `email_verification.updated`, `email_verification_list.created`, `email_verification_list.updated` |
| Campagna | `campaign.created`, `campaign.updated`, `campaign.deleted`, `campaign.scheduled`, `campaign.queued`, `campaign.sending`, `campaign.testing`, `campaign.sent`, `campaign.canceled`, `campaign.archived` |

Per il significato di ogni evento, vedi [Tipi di evento](/it/docs/webhooks/event-types/).

## Restituisce

- `ok` (boolean): `true` se l’endpoint ha risposto con uno stato 2xx.

- `status_code` (integer): Lo stato HTTP del tuo endpoint. `0` se Emailit non è riuscito a connettersi, se la richiesta è andata in timeout dopo 30 secondi, se l’endpoint ha restituito un reindirizzamento (i reindirizzamenti non vengono seguiti) o se l’URL punta a un indirizzo bloccato.

- `body` (string): I primi 2000 caratteri della risposta dell’endpoint, oppure l’errore di connessione.

- `type` (string): Il tipo di evento inviato.

- `payload` (object[]): L’array JSON esatto che è stato inviato.

Restituisce `400` se `type` manca o è sconosciuto, `404` se il webhook non esiste e `429` quando superi il limite dei test.

**Richiesta** `POST /webhooks/{id}/test`

**cURL**

```bash
curl -X POST https://api.emailit.com/v2/webhooks/wh_3NGa6raJ3s1VJ75lO9km6Dqg4cQ/test \
  -H "Authorization: Bearer $EMAILIT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "type": "email.delivered" }'
```

**Node.js**

```javascript
const res = await fetch('https://api.emailit.com/v2/webhooks/wh_3NGa6raJ3s1VJ75lO9km6Dqg4cQ/test', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.EMAILIT_API_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({ type: 'email.delivered' }),
});
const { ok, status_code, body } = await res.json();
```

**Python**

```python
import os, requests

r = requests.post(
    "https://api.emailit.com/v2/webhooks/wh_3NGa6raJ3s1VJ75lO9km6Dqg4cQ/test",
    headers={"Authorization": f"Bearer {os.environ['EMAILIT_API_KEY']}"},
    json={"type": "email.delivered"},
)
result = r.json()
```

**PHP**

```php
$client = new GuzzleHttp\Client(['base_uri' => 'https://api.emailit.com/v2/']);

$response = $client->post('webhooks/wh_3NGa6raJ3s1VJ75lO9km6Dqg4cQ/test', [
    'headers' => ['Authorization' => 'Bearer ' . getenv('EMAILIT_API_KEY')],
    'json' => ['type' => 'email.delivered'],
]);
$result = json_decode($response->getBody(), true);
```

**200**

```json
{
  "ok": true,
  "status_code": 200,
  "type": "email.delivered",
  "payload": [
    {
      "event_id": "evt_test_3G0pUekgBm1uIxi9m4C380H70Zq",
      "type": "email.delivered",
      "object": {
        "id": "eml_test_001",
        "email_id": 12345,
        "message_id": "<test-token@mydomain.com>",
        "from": "sender@mydomain.com",
        "to": "recipient@example.com",
        "subject": "Test email",
        "status": "delivered",
        "delivered_at": "2026-01-15T10:30:00.000Z"
      },
      "data": {
        "object": {
          "id": "eml_test_001",
          "email_id": 12345,
          "message_id": "<test-token@mydomain.com>",
          "from": "sender@mydomain.com",
          "to": "recipient@example.com",
          "subject": "Test email",
          "status": "delivered",
          "delivered_at": "2026-01-15T10:30:00.000Z"
        }
      }
    }
  ],
  "body": "{\"received\":true}"
}
```

**400**

```json
{
  "error": "Unknown event type"
}
```

**429**

```json
{
  "statusCode": 429,
  "error": "Too Many Requests",
  "message": "Rate limit exceeded, retry in 1 minute"
}
```

---
Fonte: https://emailit.com/it/docs/api-reference/webhooks/test/

## Ruota il secret di firma — POST /webhooks/{id}/reset-secret

> Sostituisci il secret di firma di un webhook. Ogni consegna successiva alla rotazione, compresi i nuovi tentativi, viene firmata con il nuovo secret.

# Ruota il secret di firma

Genera un nuovo secret di firma per il webhook e lo restituisce. Richiede una chiave API con il permesso `full`.

Il vecchio secret smette subito di essere usato: ogni richiesta inviata dopo la rotazione, compresi i nuovi tentativi di eventi precedenti, viene firmata con il nuovo secret. Non c’è un periodo di sovrapposizione, quindi aggiorna il secret nel tuo endpoint subito dopo la rotazione, oppure accetta entrambi i secret per un breve periodo durante il passaggio. Vedi [Verifica le firme dei webhook](/it/docs/webhooks/request-signature/).

`POST /webhooks/{id}/reset-secret`

## Parametri di percorso

- `id` (string, obbligatorio): L’ID del webhook (`wh_…`) o il nome del webhook.

## Restituisce

Restituisce l’oggetto webhook con il nuovo `secret` (`whsec_` seguito da 64 caratteri esadecimali). Restituisce `404` se il webhook non esiste.

**Richiesta** `POST /webhooks/{id}/reset-secret`

**cURL**

```bash
curl -X POST https://api.emailit.com/v2/webhooks/wh_3NGa6raJ3s1VJ75lO9km6Dqg4cQ/reset-secret \
  -H "Authorization: Bearer $EMAILIT_API_KEY"
```

**Node.js**

```javascript
const res = await fetch('https://api.emailit.com/v2/webhooks/wh_3NGa6raJ3s1VJ75lO9km6Dqg4cQ/reset-secret', {
  method: 'POST',
  headers: { Authorization: `Bearer ${process.env.EMAILIT_API_KEY}` },
});
const { secret } = await res.json();
```

**Python**

```python
import os, requests

r = requests.post(
    "https://api.emailit.com/v2/webhooks/wh_3NGa6raJ3s1VJ75lO9km6Dqg4cQ/reset-secret",
    headers={"Authorization": f"Bearer {os.environ['EMAILIT_API_KEY']}"},
)
secret = r.json()["secret"]
```

**PHP**

```php
$client = new GuzzleHttp\Client(['base_uri' => 'https://api.emailit.com/v2/']);

$response = $client->post('webhooks/wh_3NGa6raJ3s1VJ75lO9km6Dqg4cQ/reset-secret', [
    'headers' => ['Authorization' => 'Bearer ' . getenv('EMAILIT_API_KEY')],
]);
$secret = json_decode($response->getBody(), true)['secret'];
```

**200**

```json
{
  "object": "webhook",
  "id": "wh_3NGa6raJ3s1VJ75lO9km6Dqg4cQ",
  "name": "Order notifications",
  "url": "https://acme.com/webhooks/emailit",
  "all_events": false,
  "enabled": true,
  "events": ["email.delivered", "email.bounced", "email.complained"],
  "filter": null,
  "last_used_at": "2026-10-01T12:58:40.000000+00:00",
  "created_at": "2026-08-14T09:12:03.000000+00:00",
  "updated_at": "2026-10-01T13:20:11.000000+00:00",
  "secret": "whsec_a0a593d006bdec5aff2f21e88afd543ba239431acbe7d8dc7a9723d76e0a64e2"
}
```

**404**

```json
{
  "error": "Webhook not found"
}
```

---
Fonte: https://emailit.com/it/docs/api-reference/webhooks/reset-secret/

## Ritenta le richieste non riuscite — POST /webhooks/{id}/retry-failed

> Rimetti in coda per la consegna tutte le richieste webhook non riuscite definitivamente negli ultimi 7 giorni e riattiva il webhook.

# Ritenta le richieste non riuscite

Rimette in coda per la consegna tutte le richieste di questo webhook non riuscite definitivamente negli ultimi 7 giorni. Richiede una chiave API con il permesso `full`.

Una richiesta non riesce definitivamente dopo l’ultimo nuovo tentativo automatico (11 tentativi nell’arco di diversi giorni; vedi [Nuovi tentativi ed errori](/it/docs/webhooks/retries-and-failures/)). Le richieste ritentate ripartono con un calendario completo di nuovi tentativi e vengono consegnate entro pochi secondi. Se almeno una richiesta viene messa in coda e il webhook era disattivato, ad esempio dopo 3 giorni di errori continui, il webhook viene riattivato.

Prima correggi l’endpoint, altrimenti le richieste non riusciranno di nuovo. Per ritentare una sola richiesta, usa [Ritenta una richiesta](/it/docs/api-reference/webhooks/retry-request/).

`POST /webhooks/{id}/retry-failed`

## Parametri di percorso

- `id` (string, obbligatorio): L’ID del webhook (`wh_…`) o il nome del webhook.

## Restituisce

- `retried` (integer): Numero di richieste rimesse in coda. `0` se non c’era nulla da ritentare; in quel caso lo stato di attivazione del webhook non cambia.

Restituisce `404` se il webhook non esiste.

**Richiesta** `POST /webhooks/{id}/retry-failed`

**cURL**

```bash
curl -X POST https://api.emailit.com/v2/webhooks/wh_3NGa6raJ3s1VJ75lO9km6Dqg4cQ/retry-failed \
  -H "Authorization: Bearer $EMAILIT_API_KEY"
```

**Node.js**

```javascript
const res = await fetch('https://api.emailit.com/v2/webhooks/wh_3NGa6raJ3s1VJ75lO9km6Dqg4cQ/retry-failed', {
  method: 'POST',
  headers: { Authorization: `Bearer ${process.env.EMAILIT_API_KEY}` },
});
const { retried } = await res.json();
```

**Python**

```python
import os, requests

r = requests.post(
    "https://api.emailit.com/v2/webhooks/wh_3NGa6raJ3s1VJ75lO9km6Dqg4cQ/retry-failed",
    headers={"Authorization": f"Bearer {os.environ['EMAILIT_API_KEY']}"},
)
retried = r.json()["retried"]
```

**PHP**

```php
$client = new GuzzleHttp\Client(['base_uri' => 'https://api.emailit.com/v2/']);

$response = $client->post('webhooks/wh_3NGa6raJ3s1VJ75lO9km6Dqg4cQ/retry-failed', [
    'headers' => ['Authorization' => 'Bearer ' . getenv('EMAILIT_API_KEY')],
]);
$retried = json_decode($response->getBody(), true)['retried'];
```

**200**

```json
{
  "retried": 37
}
```

**404**

```json
{
  "error": "Webhook not found"
}
```

---
Fonte: https://emailit.com/it/docs/api-reference/webhooks/retry-failed/

## Ritenta una richiesta — POST /webhooks/{id}/requests/{request_id}/retry

> Rimetti in coda per la consegna una singola richiesta webhook non riuscita definitivamente e riattiva il webhook se era disattivato.

# Ritenta una richiesta

Rimette in coda per la consegna una richiesta webhook non riuscita definitivamente, con un nuovo calendario dei nuovi tentativi. Se il webhook era disattivato, viene riattivato. Richiede una chiave API con il permesso `full`.

In questo modo puoi ritentare solo le richieste che hanno esaurito i nuovi tentativi automatici; le richieste ancora in sospeso o in fase di nuovo tentativo restituiscono `400`. Trovi gli ID delle richieste (`whr_…`) nella scheda **Requests** del webhook in **Email API → Webhooks**. Per ritentare in una volta sola tutto quello degli ultimi 7 giorni, usa [Ritenta le richieste non riuscite](/it/docs/api-reference/webhooks/retry-failed/).

`POST /webhooks/{id}/requests/{request_id}/retry`

## Parametri di percorso

- `id` (string, obbligatorio): L’ID del webhook (`wh_…`) o il nome del webhook.

- `request_id` (string, obbligatorio): L’ID della richiesta webhook (`whr_…`).

## Restituisce

- `retried` (integer): Sempre `1`.

- `id` (string): L’ID della richiesta rimessa in coda.

| Stato | Quando |
| --- | --- |
| `400` | La richiesta non è in errore definitivo, oppure non ha un evento da inviare di nuovo. |
| `404` | Il webhook non esiste, oppure la richiesta non gli appartiene. |

**Richiesta** `POST /webhooks/{id}/requests/{request_id}/retry`

**cURL**

```bash
curl -X POST https://api.emailit.com/v2/webhooks/wh_3NGa6raJ3s1VJ75lO9km6Dqg4cQ/requests/whr_3tWVVMd2eHv3R9B5DWTLtwwU05X/retry \
  -H "Authorization: Bearer $EMAILIT_API_KEY"
```

**Node.js**

```javascript
const res = await fetch(
  'https://api.emailit.com/v2/webhooks/wh_3NGa6raJ3s1VJ75lO9km6Dqg4cQ/requests/whr_3tWVVMd2eHv3R9B5DWTLtwwU05X/retry',
  { method: 'POST', headers: { Authorization: `Bearer ${process.env.EMAILIT_API_KEY}` } },
);
const result = await res.json();
```

**Python**

```python
import os, requests

r = requests.post(
    "https://api.emailit.com/v2/webhooks/wh_3NGa6raJ3s1VJ75lO9km6Dqg4cQ/requests/whr_3tWVVMd2eHv3R9B5DWTLtwwU05X/retry",
    headers={"Authorization": f"Bearer {os.environ['EMAILIT_API_KEY']}"},
)
result = r.json()
```

**PHP**

```php
$client = new GuzzleHttp\Client(['base_uri' => 'https://api.emailit.com/v2/']);

$response = $client->post('webhooks/wh_3NGa6raJ3s1VJ75lO9km6Dqg4cQ/requests/whr_3tWVVMd2eHv3R9B5DWTLtwwU05X/retry', [
    'headers' => ['Authorization' => 'Bearer ' . getenv('EMAILIT_API_KEY')],
]);
$result = json_decode($response->getBody(), true);
```

**200**

```json
{
  "retried": 1,
  "id": "whr_3tWVVMd2eHv3R9B5DWTLtwwU05X"
}
```

**400**

```json
{
  "error": "Only permanently failed requests can be retried"
}
```

**404**

```json
{
  "error": "Webhook request not found"
}
```

---
Fonte: https://emailit.com/it/docs/api-reference/webhooks/retry-request/
