Webhooks
Mailpark POSTs events to your URL as they happen: deliveries, bounces, complaints, opens, clicks, unsubscribes, sequence entries and exits, held broadcasts. Each request is signed; see verifying webhooks.
Failed deliveries are retried for up to 24 hours. Deduplicate on the event id.
type Webhook = {
id: string; url: string;
event_kinds: WebhookKind[];
status: "active" | "failing" | "disabled";
failing_since: string | null;
signing_secret?: string; // only in the create response
created_at: string;
};
type WebhookKind = "email.sent" | "email.delivered" | "email.bounced" | "email.complained"
| "email.opened" | "email.clicked" | "email.unsubscribed"
| "sequence.entered" | "sequence.exited" | "broadcast.held" | "account.paused";Add a webhook
/v1/webhooksStarts sending the chosen event kinds to your URL. The response includes signing_secret, shown only once: store it as an environment variable.
webhooks:writeBody
urlstringrequiredHTTPS endpoint that accepts POST.
event_kindsWebhookKind[]requirede.g.
email.bounced,email.complained.
curl -X POST https://api.mailpark.io/v1/webhooks \
-H "Authorization: Bearer $MAILPARK_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://acme.dev/api/mailpark-webhook",
"event_kinds": [
"email.bounced",
"email.complained",
"email.unsubscribed"
]
}'{
"id": "wh_3Nd8",
"url": "https://acme.dev/api/mailpark-webhook",
"event_kinds": [
"email.bounced",
"email.complained",
"email.unsubscribed"
],
"status": "active",
"failing_since": null,
"created_at": "2026-10-22T10:02:11Z",
"signing_secret": "whsec_9f8e7d6c5b4a"
}curl https://api.mailpark.io/v1/webhooks \
-H "Authorization: Bearer $MAILPARK_API_KEY"{
"data": [
{
"id": "wh_3Nd8",
"url": "https://acme.dev/api/mailpark-webhook",
"event_kinds": [
"email.bounced",
"email.complained",
"email.unsubscribed"
],
"status": "active",
"failing_since": null,
"created_at": "2026-10-22T10:02:11Z"
}
],
"next_cursor": null
}curl https://api.mailpark.io/v1/webhooks/wh_3Nd8 \
-H "Authorization: Bearer $MAILPARK_API_KEY"{
"id": "wh_3Nd8",
"url": "https://acme.dev/api/mailpark-webhook",
"event_kinds": [
"email.bounced",
"email.complained",
"email.unsubscribed"
],
"status": "active",
"failing_since": null,
"created_at": "2026-10-22T10:02:11Z"
}Delete a webhook
/v1/webhooks/{id}Stops sending events to it.
webhooks:writePath parameters
idstringrequiredwh_…
curl -X DELETE https://api.mailpark.io/v1/webhooks/wh_3Nd8 \
-H "Authorization: Bearer $MAILPARK_API_KEY"{
"deleted": true
}Send a test event
/v1/webhooks/{id}/testDelivers a sample event to the endpoint now and returns the result, including the status code your server answered with.
Path parameters
idstringrequiredwh_…
Body
kindWebhookKindWhich event to send. Default: the first of the webhook's kinds.
curl -X POST https://api.mailpark.io/v1/webhooks/wh_3Nd8/test \
-H "Authorization: Bearer $MAILPARK_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"kind": "email.bounced"
}'{
"id": "dlv_9Qa1",
"webhook_id": "wh_3Nd8",
"event_id": "evt_5Rc2",
"kind": "email.bounced",
"attempt": 1,
"status": "succeeded",
"status_code": 200,
"response_ms": 84,
"payload": {
"id": "evt_5Rc2",
"kind": "email.bounced",
"created_at": "2026-10-22T10:02:11Z",
"data": {
"message_id": "msg_01JB4Q7Z2K",
"type": "transactional",
"to": "jane@example.com",
"contact_id": "con_7Yt1",
"template": "password-reset",
"bounce_type": "hard",
"environment": "test"
}
},
"created_at": "2026-10-22T10:02:11Z"
}List deliveries
/v1/webhooks/{id}/deliveriesRecent delivery attempts with status codes and response times. retrying also covers "queued, first attempt not made yet".
Path parameters
idstringrequiredwh_…
Query parameters
limitintegerHow many to return, 1–100. Default 50.
cursorstringThe
next_cursorfrom the previous page.
curl https://api.mailpark.io/v1/webhooks/wh_3Nd8/deliveries \
-H "Authorization: Bearer $MAILPARK_API_KEY"{
"data": [
{
"id": "dlv_9Qa1",
"webhook_id": "wh_3Nd8",
"event_id": "evt_5Rc2",
"kind": "email.bounced",
"attempt": 1,
"status": "succeeded",
"status_code": 200,
"response_ms": 84,
"payload": {
"id": "evt_5Rc2",
"kind": "email.bounced",
"created_at": "2026-10-22T10:02:11Z",
"data": {
"message_id": "msg_01JB4Q7Z2K",
"type": "transactional",
"to": "jane@example.com",
"contact_id": "con_7Yt1",
"template": "password-reset",
"bounce_type": "hard",
"environment": "test"
}
},
"created_at": "2026-10-22T10:02:11Z"
}
],
"next_cursor": null
}Resend a delivery
/v1/webhooks/{id}/deliveries/{delivery_id}/resendSends the same event again, as a new attempt.
Path parameters
idstringrequiredwh_…delivery_idstringrequireddlv_…
curl -X POST https://api.mailpark.io/v1/webhooks/wh_3Nd8/deliveries/dlv_9Qa1/resend \
-H "Authorization: Bearer $MAILPARK_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'{
"id": "dlv_9Qa2",
"webhook_id": "wh_3Nd8",
"event_id": "evt_5Rc2",
"kind": "email.bounced",
"attempt": 2,
"status": "succeeded",
"status_code": 200,
"response_ms": 84,
"payload": {
"id": "evt_5Rc2",
"kind": "email.bounced",
"created_at": "2026-10-22T10:02:11Z",
"data": {
"message_id": "msg_01JB4Q7Z2K",
"type": "transactional",
"to": "jane@example.com",
"contact_id": "con_7Yt1",
"template": "password-reset",
"bounce_type": "hard",
"environment": "test"
}
},
"created_at": "2026-10-22T10:02:11Z"
}