Webhooks
Webhook management operations.
/webhooks
List webhooks
Returns the webhook endpoints registered across the authenticated user's sending domains,
newest first. Each webhook lists its target url, subscribed events, and active state.
The signing secret is never returned here — it is shown only once, at creation. Requires the
webhooks:read scope.
Parameters
|
Name
|
In
|
Description
|
|---|---|---|
sort
|
query | Comma-separated sort fields; prefix a field with - for descending, e.g. sort=-created_at,name. Defaults to newest-first. Only allow-listed fields are accepted; an unsupported sort returns 400. |
include
|
query | Comma-separated related resources to embed in the response included member (JSON:API compound documents). Example: include=records,webhooks. Nested paths use dot notation, max depth 2. Relationships not declared by the resource, or over-deep paths, return 400. |
fields
|
query | Per-type sparse fieldsets. Example: fields[domains]=name,status restricts the returned attributes for that type. The type must be present in the document and each field must be a known attribute, otherwise 400 is returned. |
page
|
query | Cursor-based pagination, e.g. page[cursor]=eyJpZCI6...&page[size]=50. The cursor is an opaque token issued by the API — take it from the response's links.next / links.prev URLs or meta.next_cursor / meta.prev_cursor; never construct one. size defaults to 25 and is silently capped at 100 (out-of-range or non-numeric values fall back to the default). An invalid or expired cursor falls back to the first page; a cursor replayed with a different sort than it was issued under returns 400; unknown page members such as page[number] return 400. Follow links.next until it is null (or meta.has_more is false) to traverse a collection; links.first restarts traversal. Link URLs carry these parameters URL-encoded (page%5Bcursor%5D=...). |
curl -X GET https://api.minimailer.app/webhooks \ -H "Authorization: Bearer $MINIMAILER_API_TOKEN" \ -H "Accept: application/vnd.api+json"
Responses
|
Status
|
Description
|
|---|---|
| 400 |
The include or fields query parameter is not supported (unknown relationship, over-deep include, or unknown sparse-fieldset type or field).
ErrorDocument
|
| 200 |
Webhooks retrieved.
WebhookCollectionDocument
|
| 401 |
Authentication is required.
ErrorDocument
|
| 403 |
The token lacks the scope this operation requires (error code missing_scope), or the request breaks a JSON:API protocol rule (client_generated_id, unsupported_relationship_update). Never returned for a record that belongs to another account — that case is a 404.
ErrorDocument
|
| 406 |
The Accept header mentions the JSON:API media type only in instances modified by disallowed media type parameters (or only with unsupported ext extensions), so no acceptable representation remains.
ErrorDocument
|
| 429 |
The request was rate limited. Branch on the error code: rate_limited means the account exceeded its API rate limit, and agent_throttled means the agent named by agent_id has a restricted sender reputation and has exhausted the send allowance for its tier.
ErrorDocument
|
/webhooks
Create a webhook
Registers a webhook endpoint on one of your sending domains and subscribes it to a set of
event types (for example email.delivered, email.bounced, email.opened,
inbound_email.received, campaign.sent, domain.verified). MiniMailer POSTs each matching
event to your url.
The response includes a whsec_-prefixed signing secret once — store it now. Every
delivery is signed with it following the Standard Webhooks
spec, so your endpoint can verify authenticity. Deliveries are retried with backoff, and an
endpoint that keeps failing is deactivated.
Requires the webhooks:write scope.
Request body
application/vnd.api+json
— CreateWebhookRequestDocument
|
Attribute
|
Type
|
Description
|
|---|---|---|
name
required
|
string | |
url
required
|
string | HTTPS endpoint URL that will receive webhook deliveries. |
events
required
|
array |
curl -X POST https://api.minimailer.app/webhooks \ -H "Authorization: Bearer $MINIMAILER_API_TOKEN" \ -H "Accept: application/vnd.api+json" \ -H "Content-Type: application/vnd.api+json" \ -d '{"data":{"type":"webhooks","attributes":{"name":"...","url":"...","events":[]}}}'
Responses
|
Status
|
Description
|
|---|---|
| 201 |
Webhook created.
WebhookDocument
|
| 401 |
Authentication is required.
ErrorDocument
|
| 403 |
The token lacks the scope this operation requires (error code missing_scope), or the request breaks a JSON:API protocol rule (client_generated_id, unsupported_relationship_update). Never returned for a record that belongs to another account — that case is a 404.
ErrorDocument
|
| 404 |
The referenced sending domain does not exist or belongs to another account.
ErrorDocument
|
| 415 |
The request Content-Type must be application/vnd.api+json, with no media type parameters other than profile (ext is rejected — no JSON:API extensions are supported — as is any other parameter such as charset).
ErrorDocument
|
| 422 |
The request document failed validation.
ValidationErrorDocument
|
| 409 |
The request conflicts with the endpoint or current state. Branch on the error code: conflict — the document's resource type does not match the endpoint, its id does not match the resource being updated, or an idempotency key was reused with a different payload; agent_category_conflict — the agent_id names an identity already bound to the other kind of mail (one agent identity sends either transactional or marketing mail, never both; an identity dormant for 30 days may rebind). (Creating with a client-generated id and updating relationships on an endpoint that does not support them return 403 instead.)
ErrorDocument
|
| 406 |
The Accept header mentions the JSON:API media type only in instances modified by disallowed media type parameters (or only with unsupported ext extensions), so no acceptable representation remains.
ErrorDocument
|
| 429 |
The request was rate limited. Branch on the error code: rate_limited means the account exceeded its API rate limit, and agent_throttled means the agent named by agent_id has a restricted sender reputation and has exhausted the send allowance for its tier.
ErrorDocument
|
/webhooks/{webhook}
Show a webhook
Returns a single webhook owned by the authenticated user, including its target url,
subscribed events, and active state. The signing secret is not included. Requires the
webhooks:read scope.
Parameters
|
Name
|
In
|
Description
|
|---|---|---|
include
|
query | Comma-separated related resources to embed in the response included member (JSON:API compound documents). Example: include=records,webhooks. Nested paths use dot notation, max depth 2. Relationships not declared by the resource, or over-deep paths, return 400. |
fields
|
query | Per-type sparse fieldsets. Example: fields[domains]=name,status restricts the returned attributes for that type. The type must be present in the document and each field must be a known attribute, otherwise 400 is returned. |
webhook
required
|
path | The webhook identifier. |
curl -X GET https://api.minimailer.app/webhooks/{webhook} \ -H "Authorization: Bearer $MINIMAILER_API_TOKEN" \ -H "Accept: application/vnd.api+json"
Responses
|
Status
|
Description
|
|---|---|
| 400 |
The include or fields query parameter is not supported (unknown relationship, over-deep include, or unknown sparse-fieldset type or field).
ErrorDocument
|
| 200 |
Webhook retrieved.
WebhookDocument
|
| 401 |
Authentication is required.
ErrorDocument
|
| 403 |
The token lacks the scope this operation requires (error code missing_scope), or the request breaks a JSON:API protocol rule (client_generated_id, unsupported_relationship_update). Never returned for a record that belongs to another account — that case is a 404.
ErrorDocument
|
| 404 |
The resource does not exist, or it belongs to another account. The two cases return the same status, error code and detail by design, so the error document does not confirm that an identifier is in use.
ErrorDocument
|
| 406 |
The Accept header mentions the JSON:API media type only in instances modified by disallowed media type parameters (or only with unsupported ext extensions), so no acceptable representation remains.
ErrorDocument
|
| 429 |
The request was rate limited. Branch on the error code: rate_limited means the account exceeded its API rate limit, and agent_throttled means the agent named by agent_id has a restricted sender reputation and has exhausted the send allowance for its tier.
ErrorDocument
|
/webhooks/{webhook}
Update a webhook
Updates a webhook owned by the authenticated user — its name, target url, the set of
subscribed events, or its active flag (set active: false to pause deliveries without
deleting the endpoint). Set rotate_secret: true to rotate the signing secret: a new
secret is generated server-side and returned once in the response, while the previous
secret keeps verifying deliveries for a 24-hour grace window. The secret value itself
cannot be chosen by the client. Requires the webhooks:write scope.
Parameters
|
Name
|
In
|
Description
|
|---|---|---|
webhook
required
|
path | The webhook identifier. |
Request body
application/vnd.api+json
— UpdateWebhookRequestDocument
|
Attribute
|
Type
|
Description
|
|---|---|---|
name
|
string | |
url
|
string | |
events
|
array | |
active
|
boolean | |
rotate_secret
|
boolean |
curl -X PATCH https://api.minimailer.app/webhooks/{webhook} \ -H "Authorization: Bearer $MINIMAILER_API_TOKEN" \ -H "Accept: application/vnd.api+json" \ -H "Content-Type: application/vnd.api+json" \ -d '{"data":{"type":"webhooks","attributes":{"name":"...","url":"...","events":[],"active":true,"rotate_secret":true}}}'
Responses
|
Status
|
Description
|
|---|---|
| 200 |
Webhook updated.
WebhookDocument
|
| 401 |
Authentication is required.
ErrorDocument
|
| 403 |
The token lacks the scope this operation requires (error code missing_scope), or the request breaks a JSON:API protocol rule (client_generated_id, unsupported_relationship_update). Never returned for a record that belongs to another account — that case is a 404.
ErrorDocument
|
| 404 |
The resource does not exist, or it belongs to another account. The two cases return the same status, error code and detail by design, so the error document does not confirm that an identifier is in use.
ErrorDocument
|
| 415 |
The request Content-Type must be application/vnd.api+json, with no media type parameters other than profile (ext is rejected — no JSON:API extensions are supported — as is any other parameter such as charset).
ErrorDocument
|
| 422 |
The request document failed validation.
ValidationErrorDocument
|
| 409 |
The request conflicts with the endpoint or current state. Branch on the error code: conflict — the document's resource type does not match the endpoint, its id does not match the resource being updated, or an idempotency key was reused with a different payload; agent_category_conflict — the agent_id names an identity already bound to the other kind of mail (one agent identity sends either transactional or marketing mail, never both; an identity dormant for 30 days may rebind). (Creating with a client-generated id and updating relationships on an endpoint that does not support them return 403 instead.)
ErrorDocument
|
| 406 |
The Accept header mentions the JSON:API media type only in instances modified by disallowed media type parameters (or only with unsupported ext extensions), so no acceptable representation remains.
ErrorDocument
|
| 429 |
The request was rate limited. Branch on the error code: rate_limited means the account exceeded its API rate limit, and agent_throttled means the agent named by agent_id has a restricted sender reputation and has exhausted the send allowance for its tier.
ErrorDocument
|
/webhooks/{webhook}
Delete a webhook
Permanently deletes a webhook owned by the authenticated user. No further events are
delivered to its endpoint and its signing secret is invalidated. Past delivery records are
retained. To pause deliveries temporarily, set active: false instead. Requires the
webhooks:write scope.
Parameters
|
Name
|
In
|
Description
|
|---|---|---|
webhook
required
|
path | The webhook identifier. |
curl -X DELETE https://api.minimailer.app/webhooks/{webhook} \ -H "Authorization: Bearer $MINIMAILER_API_TOKEN" \ -H "Accept: application/vnd.api+json"
Responses
|
Status
|
Description
|
|---|---|
| 204 | Webhook deleted. |
| 401 |
Authentication is required.
ErrorDocument
|
| 403 |
The token lacks the scope this operation requires (error code missing_scope), or the request breaks a JSON:API protocol rule (client_generated_id, unsupported_relationship_update). Never returned for a record that belongs to another account — that case is a 404.
ErrorDocument
|
| 404 |
The resource does not exist, or it belongs to another account. The two cases return the same status, error code and detail by design, so the error document does not confirm that an identifier is in use.
ErrorDocument
|
| 406 |
The Accept header mentions the JSON:API media type only in instances modified by disallowed media type parameters (or only with unsupported ext extensions), so no acceptable representation remains.
ErrorDocument
|
| 429 |
The request was rate limited. Branch on the error code: rate_limited means the account exceeded its API rate limit, and agent_throttled means the agent named by agent_id has a restricted sender reputation and has exhausted the send allowance for its tier.
ErrorDocument
|
/webhooks/{webhook}/deliveries
List webhook deliveries
Returns the delivery attempts made for a webhook owned by the authenticated user, newest
first — each with the event delivered, the response status, and the outcome. Use it to audit
which events reached your endpoint and to find failed deliveries to replay. Requires the
webhooks:read scope.
Parameters
|
Name
|
In
|
Description
|
|---|---|---|
filter
|
query | Exact-match filters, e.g. filter[status]=delivered. Only the fields this endpoint allow-lists are accepted; an unsupported filter returns 400. |
sort
|
query | Comma-separated sort fields; prefix a field with - for descending, e.g. sort=-created_at,name. Defaults to newest-first. Only allow-listed fields are accepted; an unsupported sort returns 400. |
include
|
query | Comma-separated related resources to embed in the response included member (JSON:API compound documents). Example: include=records,webhooks. Nested paths use dot notation, max depth 2. Relationships not declared by the resource, or over-deep paths, return 400. |
fields
|
query | Per-type sparse fieldsets. Example: fields[domains]=name,status restricts the returned attributes for that type. The type must be present in the document and each field must be a known attribute, otherwise 400 is returned. |
page
|
query | Cursor-based pagination, e.g. page[cursor]=eyJpZCI6...&page[size]=50. The cursor is an opaque token issued by the API — take it from the response's links.next / links.prev URLs or meta.next_cursor / meta.prev_cursor; never construct one. size defaults to 25 and is silently capped at 100 (out-of-range or non-numeric values fall back to the default). An invalid or expired cursor falls back to the first page; a cursor replayed with a different sort than it was issued under returns 400; unknown page members such as page[number] return 400. Follow links.next until it is null (or meta.has_more is false) to traverse a collection; links.first restarts traversal. Link URLs carry these parameters URL-encoded (page%5Bcursor%5D=...). |
webhook
required
|
path | The webhook identifier. |
curl -X GET https://api.minimailer.app/webhooks/{webhook}/deliveries \ -H "Authorization: Bearer $MINIMAILER_API_TOKEN" \ -H "Accept: application/vnd.api+json"
Responses
|
Status
|
Description
|
|---|---|
| 400 |
The include or fields query parameter is not supported (unknown relationship, over-deep include, or unknown sparse-fieldset type or field).
ErrorDocument
|
| 200 |
Webhook deliveries retrieved.
OutboundWebhookCollectionDocument
|
| 401 |
Authentication is required.
ErrorDocument
|
| 403 |
The token lacks the scope this operation requires (error code missing_scope), or the request breaks a JSON:API protocol rule (client_generated_id, unsupported_relationship_update). Never returned for a record that belongs to another account — that case is a 404.
ErrorDocument
|
| 404 |
The resource does not exist, or it belongs to another account. The two cases return the same status, error code and detail by design, so the error document does not confirm that an identifier is in use.
ErrorDocument
|
| 406 |
The Accept header mentions the JSON:API media type only in instances modified by disallowed media type parameters (or only with unsupported ext extensions), so no acceptable representation remains.
ErrorDocument
|
| 429 |
The request was rate limited. Branch on the error code: rate_limited means the account exceeded its API rate limit, and agent_throttled means the agent named by agent_id has a restricted sender reputation and has exhausted the send allowance for its tier.
ErrorDocument
|
/deliveries/{outboundWebhook}
Show a webhook delivery
Returns a single webhook delivery attempt owned by the authenticated user, including the
signed payload that was sent and the endpoint's response. Requires the webhooks:read scope.
Parameters
|
Name
|
In
|
Description
|
|---|---|---|
include
|
query | Comma-separated related resources to embed in the response included member (JSON:API compound documents). Example: include=records,webhooks. Nested paths use dot notation, max depth 2. Relationships not declared by the resource, or over-deep paths, return 400. |
fields
|
query | Per-type sparse fieldsets. Example: fields[domains]=name,status restricts the returned attributes for that type. The type must be present in the document and each field must be a known attribute, otherwise 400 is returned. |
outboundWebhook
required
|
path | The webhook delivery identifier. |
curl -X GET https://api.minimailer.app/deliveries/{outboundWebhook} \ -H "Authorization: Bearer $MINIMAILER_API_TOKEN" \ -H "Accept: application/vnd.api+json"
Responses
|
Status
|
Description
|
|---|---|
| 400 |
The include or fields query parameter is not supported (unknown relationship, over-deep include, or unknown sparse-fieldset type or field).
ErrorDocument
|
| 200 |
Webhook delivery retrieved.
OutboundWebhookDocument
|
| 401 |
Authentication is required.
ErrorDocument
|
| 403 |
The token lacks the scope this operation requires (error code missing_scope), or the request breaks a JSON:API protocol rule (client_generated_id, unsupported_relationship_update). Never returned for a record that belongs to another account — that case is a 404.
ErrorDocument
|
| 404 |
The resource does not exist, or it belongs to another account. The two cases return the same status, error code and detail by design, so the error document does not confirm that an identifier is in use.
ErrorDocument
|
| 406 |
The Accept header mentions the JSON:API media type only in instances modified by disallowed media type parameters (or only with unsupported ext extensions), so no acceptable representation remains.
ErrorDocument
|
| 429 |
The request was rate limited. Branch on the error code: rate_limited means the account exceeded its API rate limit, and agent_throttled means the agent named by agent_id has a restricted sender reputation and has exhausted the send allowance for its tier.
ErrorDocument
|
/deliveries/{outboundWebhook}/replay
Replay a webhook delivery
Re-sends a past webhook delivery to its endpoint, reusing the original event payload with a
fresh signature and timestamp. Use it to recover events your endpoint missed during downtime.
This creates a new delivery attempt rather than mutating the original. Requires the
webhooks:write scope.
Parameters
|
Name
|
In
|
Description
|
|---|---|---|
outboundWebhook
required
|
path | The webhook delivery identifier. |
curl -X POST https://api.minimailer.app/deliveries/{outboundWebhook}/replay \ -H "Authorization: Bearer $MINIMAILER_API_TOKEN" \ -H "Accept: application/vnd.api+json"
Responses
|
Status
|
Description
|
|---|---|
| 202 |
Webhook delivery replay accepted.
OutboundWebhookDocument
|
| 401 |
Authentication is required.
ErrorDocument
|
| 403 |
The token lacks the scope this operation requires (error code missing_scope), or the request breaks a JSON:API protocol rule (client_generated_id, unsupported_relationship_update). Never returned for a record that belongs to another account — that case is a 404.
ErrorDocument
|
| 404 |
The resource does not exist, or it belongs to another account. The two cases return the same status, error code and detail by design, so the error document does not confirm that an identifier is in use.
ErrorDocument
|
| 406 |
The Accept header mentions the JSON:API media type only in instances modified by disallowed media type parameters (or only with unsupported ext extensions), so no acceptable representation remains.
ErrorDocument
|
| 429 |
The request was rate limited. Branch on the error code: rate_limited means the account exceeded its API rate limit, and agent_throttled means the agent named by agent_id has a restricted sender reputation and has exhausted the send allowance for its tier.
ErrorDocument
|