API reference
Webhook endpoints
Manage the endpoints that receive events. For the shape of an event and how to verify its signature, see the Webhooks guide — this page is the registration side of it.
Why use this
For example
Your infrastructure-as-code registers the production endpoint on first deploy and writes the returned secret into your secret manager, so a rebuilt environment wires itself up.
Example
import { YourMail } from "yourmail";
const yourmail = new YourMail(process.env.YOURMAIL_API_KEY!);
const hook = await yourmail.webhooks.create({
url: "https://acme.com/hooks/yourmail",
events: ["email.bounced", "email.complained"], // or ["*"]
});
// hook.secret is the signing secret — returned here and nowhere else.
await yourmail.webhooks.update(hook.id, { enabled: false });
await yourmail.webhooks.delete(hook.id);curl -X POST https://api.yourmail.dev/v1/webhooks \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "url": "https://acme.com/hooks/yourmail", "events": ["*"] }'
curl -X PATCH https://api.yourmail.dev/v1/webhooks/HOOK_ID \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "enabled": true }'Response
// 201 Created — the ONLY response that carries the secret
{
"id": "w1...",
"url": "https://acme.com/hooks/yourmail",
"events": ["*"],
"enabled": true,
"description": null,
"secret": "whsec_...",
"consecutiveFailures": 0,
"lastAttemptAt": null,
"lastResponseStatus": null,
"lastError": null,
"suspendedByPlan": false,
"autoDisabledAt": null
}GET returns { data: [ ...endpoints ] } without secret, PATCH returns the updated endpoint (also without it), and DELETE returns { id, deleted: true }.
eventsstring[]- The event types to deliver, or ["*"] for all nine. The Webhooks guide lists them with what each one means.
secretstring- The HMAC signing secret, on the create response only. GET and PATCH omit it, so a captured list response cannot be used to forge signed deliveries. The account owner can still read it in the dashboard.
consecutiveFailuresnumber- Deliveries in a row that exhausted every retry. Resets to 0 on a success while the endpoint is still enabled, and when you re-enable it. Once we switch an endpoint off this holds the count we switched it off at — the same number the notification email quotes — so a late result from an in-flight retry cannot move it.
autoDisabledAtnumber | null- Set when YourMail switched the endpoint off after 20 consecutive exhausted deliveries. The account owner is emailed when it happens. PATCH { enabled: true } clears it.
suspendedByPlanboolean- True when a plan downgrade parked the endpoint. PATCH cannot re-enable one — raise the plan, or swap it for another in the dashboard.
lastResponseStatusnumber | null- The HTTP status of the most recent attempt. The per-attempt log, with payloads and a resend action, is on the dashboard's Deliveries tab.
Errors
Every endpoint on this page needs a full-access key. A send-only key is issued so it can be handed to something that only sends — if it could also manage the account, the scope would be decorative. See Errors for the full error shape.
validation_errorurl is not https, uses a port other than 443, is a private or link-local host, events is empty, events names a type that does not exist, or description is over 500 characters
authentication_errorThe key is send-only; managing endpoints requires a full-access key
authentication_errorThe API key is missing, malformed or revoked
validation_errorenabled: true on an endpoint your plan has suspended
validation_errorYour plan's endpoint allowance is full, or your plan does not include webhook endpoints at all
not_foundNo endpoint with that id on this account