Inbound Webhooks
Webhooks notify your application when a new email reaches an authorized MarkRelay mailbox. Use them to open support tickets, trigger workflows, archive messages, or hand new conversations to an AI agent.
Create a webhook
- Open Developer → Webhooks.
- Enter your public HTTP or HTTPS endpoint.
- Choose whether it follows your access, one domain, or selected mailboxes.
- Create the webhook and copy the
whsec_...signing secret. - Select Send test and confirm your endpoint returns a 2xx response.
The signing secret is shown when the webhook is created. Store it in your application's secret manager before closing the dialog.
Event request
POST /your-endpoint
Content-Type: application/json
X-MarkRelay-Event: email.received
X-MarkRelay-Webhook-Id: <webhook-id>
X-MarkRelay-Timestamp: 2026-07-21T12:00:00.000Z
X-MarkRelay-Signature: sha256=<signature>
{
"event": "email.received",
"webhookId": "...",
"timestamp": "2026-07-21T12:00:00.000Z",
"data": {
"id": "...",
"mailbox": "support@example.com"
}
}The data object contains the received email, including its mailbox, sender, recipients, content, and attachment information.
Verify the signature
MarkRelay signs the timestamp and raw JSON body with HMAC-SHA256. Verify the signature before parsing or processing the event:
const rawBody = await request.text();
const timestamp = request.headers.get("X-MarkRelay-Timestamp") ?? "";
const signature = request.headers.get("X-MarkRelay-Signature") ?? "";
const expected = await hmacSha256Hex(
process.env.MARKRELAY_WEBHOOK_SECRET,
timestamp + "." + rawBody,
);
if (!timingSafeEqualHex("sha256=" + expected, signature)) {
return new Response("invalid signature", { status: 401 });
}
const event = JSON.parse(rawBody);
await processEmail(event.data);
return new Response("ok");Use the exact raw body, compare signatures in constant time, and reject timestamps outside your preferred replay window.
Build a reliable receiver
- Return a 2xx response after the event has been accepted.
- Use the email ID and webhook ID to make processing idempotent.
- Move slow business logic to your own background job when possible.
- Keep the endpoint on a public hostname; redirects and local addresses are not accepted.
MarkRelay retries unsuccessful deliveries and shows recent successes, failures, and errors in the webhook dashboard. Repeatedly failing endpoints are paused to protect the rest of your mail workflow; fix the endpoint, send another test, and re-enable it.
Control what is delivered
Webhook scope can follow the owner, cover one domain, or include selected mailboxes. If the owner's mailbox access changes, webhook access follows automatically.
For sending or polling email, use the Email API.