# Webhooks API

> Enregistrez des endpoints qui reçoivent des notifications d’événements signées.

URL de base : `https://api.emailit.com/v2`. Authentifiez-vous avec `Authorization: Bearer <API key>`.

## Créer un webhook — POST /webhooks

> Enregistrez un endpoint HTTP qui reçoit des notifications d’événements signées, choisissez ses types d’événements et, à partir du forfait Pro, un filtre de contenu.

# Créer un webhook

Crée un endpoint de webhook dans votre espace de travail. Emailit envoie les événements correspondants à l’URL par lots de 100 au maximum, sous forme de tableau JSON signé avec le `secret` du webhook. Pour le format des requêtes, consultez [Requêtes de webhook](/fr/docs/webhooks/webhook-requests/). Nécessite une clé API de portée `full`.

`POST /webhooks`

## Corps de la requête

- `name` (string, obligatoire): Nom du webhook. Doit être unique dans l’espace de travail ; vous pouvez l’utiliser à la place de l’ID dans les autres endpoints de webhook.

- `url` (string, obligatoire): Endpoint qui reçoit les événements. Les URL `http` et `https` sont acceptées ; utilisez `https` en production. Emailit résout le nom d’hôte à l’enregistrement et rejette `localhost` ainsi que les adresses IP privées, locales au lien et autres adresses réservées. Les redirections ne sont pas suivies lors de la livraison : utilisez l’URL finale.

- `all_events` (boolean): Envoie tous les types d’événements, y compris ceux ajoutés ultérieurement. Par défaut : `false`. Lorsqu’il vaut `true`, `events` est ignoré.

- `enabled` (boolean): Indique si Emailit livre les événements au webhook. Par défaut : `true`.

- `events` (string[]): Types d’événements à envoyer, par exemple `["email.delivered", "email.bounced"]`. Consultez [Types d’événements](/fr/docs/webhooks/event-types/). Par défaut : `[]`, ce qui, avec `all_events: false`, signifie que le webhook ne reçoit rien. Les noms d’événements ne sont pas validés. Un type mal orthographié est enregistré, mais ne correspond jamais à aucun événement.

- `filter` (object | null): Filtre de contenu. Emailit n’envoie que les événements dont l’objet correspond aux règles. Disponible sur les forfaits Pro, Business et Custom ; un filtre avec des règles sur Pay as you go renvoie `403`.

- `filter.match` (string): `all` (par défaut) envoie un événement lorsque toutes les règles correspondent. `any` l’envoie lorsqu’au moins une règle correspond.

- `filter.rules` (object[]): 25 règles au maximum.

- `filter.rules[].field` (string, obligatoire): Chemin à points dans l’objet de l’événement, par exemple `to`, `status`, `meta.plan` ou, pour les événements de clic et d’ouverture, `email.campaign.id`. Un préfixe `payload.` est ignoré.

- `filter.rules[].operator` (string, obligatoire): `equals`, `not_equals`, `contains`, `not_contains`, `starts_with`, `ends_with`, `greater_than`, `less_than`, `is_set`, `is_not_set`, `in` ou `not_in`. Les opérateurs de texte comparent les valeurs comme des chaînes ; `greater_than` et `less_than` comparent des nombres.

- `filter.rules[].value` (any): Valeur de comparaison. Obligatoire pour tous les opérateurs sauf `is_set` et `is_not_set`. Utilisez un tableau avec `in` et `not_in`.

## Réponse

Renvoie `201 Created` avec l’objet webhook, y compris le `secret` de signature (`whsec_` suivi de 64 caractères hexadécimaux). Utilisez ce secret pour [vérifier les signatures des requêtes](/fr/docs/webhooks/request-signature/). Vous pouvez le relire avec [Récupérer un webhook](/fr/docs/api-reference/webhooks/get/) et en effectuer la rotation avec [Effectuer une rotation du secret de signature](/fr/docs/api-reference/webhooks/reset-secret/).

| Statut | Cas |
| --- | --- |
| `400` | `name` ou `url` est absent, l’URL n’est pas valide, ne peut pas être résolue ou pointe vers une adresse bloquée, ou le filtre n’est pas valide. |
| `403` | Le filtre contient des règles et votre forfait n’inclut pas les filtres de webhook. Le corps est `{"error": "plan_required", "required_plan": "pro"}`. |
| `409` | Un webhook portant ce nom existe déjà. Le corps inclut l’`id` et le `name` du webhook existant (`existing`). |
| `422` | L’espace de travail a atteint la limite de webhooks de son forfait. Le corps inclut `usage.used` et `usage.limit`. Consultez [Limites](/fr/docs/limits/). |

**Requête** `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
  }
}
```

**Filtre**

```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" }
    ]
  }
}
```

---
Source: https://emailit.com/fr/docs/api-reference/webhooks/create/

## Récupérer un webhook — GET /webhooks/{id}

> Récupérez un webhook par son ID ou son nom, avec son URL, ses types d’événements, son filtre de contenu et son secret de signature.

# Récupérer un webhook

Renvoie un webhook, recherché par ID ou par nom. C’est le seul endpoint de lecture qui renvoie le `secret` de signature. Nécessite une clé API de portée `full`.

`GET /webhooks/:id`

## Paramètres de chemin

- `id` (string, obligatoire): ID du webhook (`wh_…`) ou son nom, encodé pour l’URL.

## Réponse

Renvoie `200 OK` avec l’objet webhook, y compris `secret` et `filters_allowed` (indique si votre forfait permet au webhook d’utiliser un filtre de contenu). `last_used_at` est l’heure de la dernière livraison réussie, ou `null` si rien n’a encore été livré.

Renvoie `404` avec `error: "Webhook not found"` si aucun webhook ne correspond.

**Requête** `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"
}
```

---
Source: https://emailit.com/fr/docs/api-reference/webhooks/get/

## Mettre à jour un webhook — POST /webhooks/{id}

> Modifiez le nom, l’URL, les types d’événements, le filtre de contenu ou l’état d’activation d’un webhook, recherché par son ID ou par son nom.

# Mettre à jour un webhook

Met à jour un webhook. N’envoyez que les champs à modifier ; au moins un est obligatoire. Le secret de signature ne change pas ; pour en effectuer la rotation, utilisez [Effectuer une rotation du secret de signature](/fr/docs/api-reference/webhooks/reset-secret/). Nécessite une clé API de portée `full`.

`POST /webhooks/:id`

## Paramètres de chemin

- `id` (string, obligatoire): ID du webhook (`wh_…`) ou son nom, encodé pour l’URL.

## Corps de la requête

- `name` (string): Nouveau nom. Doit être unique dans l’espace de travail.

- `url` (string): Nouvelle URL de l’endpoint, `http` ou `https`. Validée de la même façon qu’à la [création](/fr/docs/api-reference/webhooks/create/).

- `all_events` (boolean): `true` envoie tous les types d’événements et vide la liste `events`. Si vous le définissez sur `false`, envoyez aussi `events`, sinon le webhook ne reçoit rien.

- `enabled` (boolean): `false` arrête les livraisons et `true` les reprend. Les événements qui surviennent pendant que le webhook est désactivé ne sont pas mis en file d’attente pour lui et ne sont pas envoyés plus tard.

- `events` (string[]): Remplace la liste des types d’événements. Ignoré tant que `all_events` vaut `true`. Les noms ne sont pas validés.

- `filter` (object | null): Remplace le filtre de contenu, au même format qu’à la [création](/fr/docs/api-reference/webhooks/create/). Envoyez `null` pour le supprimer. Un filtre avec des règles nécessite un forfait Pro, Business ou Custom.

## Réponse

Renvoie `200 OK` avec le webhook mis à jour. Le `secret` n’est pas inclus ; utilisez [Récupérer un webhook](/fr/docs/api-reference/webhooks/get/) pour le lire.

| Statut | Cas |
| --- | --- |
| `400` | Le corps ne contient aucun des champs ci-dessus, ou l’URL ou le filtre n’est pas valide. |
| `403` | Le filtre contient des règles et votre forfait n’inclut pas les filtres de webhook (`plan_required`). |
| `404` | Aucun webhook ne correspond à `id`. |
| `409` | Un autre webhook utilise déjà le nouveau nom. |

**Requête** `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"
}
```

---
Source: https://emailit.com/fr/docs/api-reference/webhooks/update/

## Lister les webhooks — GET /webhooks

> Listez les webhooks de votre espace de travail avec recherche, filtres et pagination par pages, ainsi que la consommation de webhooks de votre forfait.

# Lister les webhooks

Renvoie les webhooks de votre espace de travail, du plus récent au plus ancien, et le nombre de webhooks autorisés par votre forfait. Les secrets de signature ne figurent pas dans la liste. Nécessite une clé API de portée `full`.

`GET /webhooks`

## Paramètres de requête

- `page` (integer): Numéro de page, à partir de `1`. Par défaut : `1`.

- `limit` (integer): Nombre de webhooks par page, de `1` à `100`. Par défaut : `10`.

- `search` (string): Recherche insensible à la casse sur le nom ou l’URL du webhook.

- `match`, `order`, `direction`: voir [Filtrage et tri](https://emailit.com/fr/docs/api-reference/filtering/).

## Filtres et tri

Clés de filtre et de tri : voir [Filtrage et tri](https://emailit.com/fr/docs/api-reference/filtering/).

## Réponse

Renvoie `200 OK` avec les webhooks dans `data`, `next_page_url` et `previous_page_url` (`null` en début ou en fin de liste), et un objet `usage` : `used` est le nombre de webhooks de l’espace de travail, `limit` le maximum autorisé par votre forfait, et `filters_allowed` indique si votre forfait inclut les filtres de contenu.

**Requête** `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"
}
```

---
Source: https://emailit.com/fr/docs/api-reference/webhooks/list/

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

> Supprimez un webhook par son ID ou son nom. Emailit cesse d’envoyer des événements à son URL, y compris les nouvelles tentatives encore en attente.

# Supprimer un webhook

Supprime définitivement un webhook et ses abonnements aux événements. Pour interrompre temporairement les livraisons, [mettez plutôt à jour le webhook](/fr/docs/api-reference/webhooks/update/) avec `enabled: false`. Nécessite une clé API de portée `full`.

`DELETE /webhooks/:id`

## Paramètres de chemin

- `id` (string, obligatoire): ID du webhook (`wh_…`) ou son nom, encodé pour l’URL.

## Réponse

Renvoie `200 OK` avec l’`id` et le `name` du webhook supprimé, et `deleted: true`. Renvoie `404` avec `error: "Webhook not found"` si aucun webhook ne correspond.

**Requête** `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"
}
```

---
Source: https://emailit.com/fr/docs/api-reference/webhooks/delete/

## Envoyer un événement de test — POST /webhooks/{id}/test

> Envoyez un exemple d’événement signé, de n’importe quel type, à un endpoint de webhook et obtenez immédiatement la réponse de l’endpoint.

# Envoyer un événement de test

Envoie un exemple d’événement du type choisi à l’URL du webhook et renvoie la réponse de votre endpoint. Utilisez-le pour vérifier que votre endpoint est joignable et qu’il vérifie correctement les [signatures](/fr/docs/webhooks/request-signature/). Nécessite une clé API de portée `full`.

La requête a le même format, les mêmes en-têtes et la même signature qu’une livraison réelle : un tableau JSON contenant un événement dont l’`event_id` commence par `evt_test_`, signé avec le secret actuel du webhook. Elle est envoyée même si le webhook est désactivé ou n’est pas abonné à ce type, n’est pas enregistrée comme requête de webhook et ne fait l’objet d’aucune nouvelle tentative. Les données d’exemple sont fixes et ne font référence à aucun objet réel.

Vous pouvez envoyer 5 événements de test par minute depuis la même adresse IP ; au-delà, la requête renvoie `429`.

`POST /webhooks/{id}/test`

## Paramètres de chemin

- `id` (string, obligatoire): L’ID du webhook (`wh_…`) ou son nom.

## Paramètres du corps

- `type` (string, obligatoire): Le type d’événement à envoyer. L’un des types ci-dessous.

| Ressource | Types d’événements |
| --- | --- |
| E-mail | `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` |
| Domaine | `domain.created`, `domain.updated`, `domain.deleted` |
| Liste de contacts | `audience.created`, `audience.updated`, `audience.deleted` |
| Abonné | `subscriber.created`, `subscriber.updated`, `subscriber.deleted` |
| Contact | `contact.created`, `contact.updated`, `contact.deleted` |
| Modèle | `template.created`, `template.updated`, `template.deleted` |
| Blocage | `suppression.created`, `suppression.updated`, `suppression.deleted` |
| Vérification d’e-mails | `email_verification.created`, `email_verification.updated`, `email_verification_list.created`, `email_verification_list.updated` |
| Campagne | `campaign.created`, `campaign.updated`, `campaign.deleted`, `campaign.scheduled`, `campaign.queued`, `campaign.sending`, `campaign.testing`, `campaign.sent`, `campaign.canceled`, `campaign.archived` |

Pour la signification de chaque événement, consultez [Types d’événements](/fr/docs/webhooks/event-types/).

## Réponse

- `ok` (boolean): `true` si votre endpoint a répondu avec un statut 2xx.

- `status_code` (integer): Le statut HTTP de votre endpoint. `0` si Emailit n’a pas pu se connecter, si la requête a expiré au bout de 30 secondes, si l’endpoint a redirigé (les redirections ne sont pas suivies) ou si l’URL pointe vers une adresse bloquée.

- `body` (string): Les 2 000 premiers caractères de la réponse de votre endpoint, ou l’erreur de connexion.

- `type` (string): Le type d’événement envoyé.

- `payload` (object[]): Le tableau JSON exact qui a été envoyé.

Renvoie `400` si `type` est absent ou inconnu, `404` si le webhook n’existe pas, et `429` si vous dépassez la limite de tests.

**Requête** `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"
}
```

---
Source: https://emailit.com/fr/docs/api-reference/webhooks/test/

## Effectuer une rotation du secret de signature — POST /webhooks/{id}/reset-secret

> Remplacez le secret de signature d’un webhook. Chaque livraison après la rotation, nouvelles tentatives comprises, est signée avec le nouveau secret.

# Effectuer une rotation du secret de signature

Génère un nouveau secret de signature pour le webhook et le renvoie. Nécessite une clé API de portée `full`.

L’ancien secret cesse immédiatement d’être utilisé : chaque requête envoyée après la rotation, y compris les nouvelles tentatives d’événements antérieurs, est signée avec le nouveau secret. Il n’y a pas de période de chevauchement : mettez donc à jour le secret dans votre endpoint juste après la rotation, ou acceptez les deux secrets pendant un court moment, le temps de basculer. Consultez [Vérifier les signatures de webhook](/fr/docs/webhooks/request-signature/).

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

## Paramètres de chemin

- `id` (string, obligatoire): L’ID du webhook (`wh_…`) ou son nom.

## Réponse

Renvoie l’objet webhook avec le nouveau `secret` (`whsec_` suivi de 64 caractères hexadécimaux). Renvoie `404` si le webhook n’existe pas.

**Requête** `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"
}
```

---
Source: https://emailit.com/fr/docs/api-reference/webhooks/reset-secret/

## Relancer les requêtes en échec — POST /webhooks/{id}/retry-failed

> Remettez en file d’attente toutes les requêtes de webhook définitivement en échec des 7 derniers jours pour une nouvelle livraison, et réactivez le webhook.

# Relancer les requêtes en échec

Remet en file d’attente, pour une nouvelle livraison, toutes les requêtes de ce webhook définitivement en échec au cours des 7 derniers jours. Nécessite une clé API de portée `full`.

Une requête échoue définitivement après sa dernière nouvelle tentative automatique (11 tentatives sur plusieurs jours ; voir [Nouvelles tentatives et échecs](/fr/docs/webhooks/retries-and-failures/)). Les requêtes relancées repartent avec un calendrier complet de nouvelles tentatives et sont livrées en quelques secondes. Si au moins une requête est remise en file d’attente et que le webhook était désactivé, par exemple après 3 jours d’échecs continus, il est réactivé.

Corrigez d’abord votre endpoint, sinon les requêtes échoueront de nouveau. Pour relancer une seule requête, utilisez [Relancer une requête](/fr/docs/api-reference/webhooks/retry-request/).

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

## Paramètres de chemin

- `id` (string, obligatoire): L’ID du webhook (`wh_…`) ou son nom.

## Réponse

- `retried` (integer): Nombre de requêtes remises en file d’attente. `0` s’il n’y avait rien à relancer ; l’état d’activation du webhook ne change alors pas.

Renvoie `404` si le webhook n’existe pas.

**Requête** `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"
}
```

---
Source: https://emailit.com/fr/docs/api-reference/webhooks/retry-failed/

## Relancer une requête — POST /webhooks/{id}/requests/{request_id}/retry

> Remettez en file d’attente une seule requête de webhook définitivement en échec pour une nouvelle livraison, et réactivez le webhook s’il était désactivé.

# Relancer une requête

Remet en file d’attente une requête de webhook définitivement en échec pour une nouvelle livraison, avec un nouveau calendrier de nouvelles tentatives. Si le webhook était désactivé, il est réactivé. Nécessite une clé API de portée `full`.

Seules les requêtes dont les nouvelles tentatives automatiques sont épuisées peuvent être relancées de cette façon ; les requêtes encore en attente ou en cours de nouvelle tentative renvoient `400`. Les ID de requête (`whr_…`) se trouvent dans l’onglet **Requests** du webhook, sous **Email API → Webhooks**. Pour relancer en une fois toutes les requêtes des 7 derniers jours, utilisez [Relancer les requêtes en échec](/fr/docs/api-reference/webhooks/retry-failed/).

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

## Paramètres de chemin

- `id` (string, obligatoire): L’ID du webhook (`wh_…`) ou son nom.

- `request_id` (string, obligatoire): L’ID de la requête de webhook (`whr_…`).

## Réponse

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

- `id` (string): L’ID de la requête remise en file d’attente.

| Statut | Cas |
| --- | --- |
| `400` | La requête n’a pas définitivement échoué, ou elle n’a aucun événement à renvoyer. |
| `404` | Le webhook n’existe pas, ou la requête ne lui appartient pas. |

**Requête** `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"
}
```

---
Source: https://emailit.com/fr/docs/api-reference/webhooks/retry-request/
