Webhooks & signatures
Signed delivery, bounce and incoming events.
Register
An owner/admin can register five active endpoints per workspace. Public HTTPS port 443 is required; private destinations and redirects are blocked. Store the returned secret immediately.
inboxit webhooks create --url https://yourbrand.com/hooks/inboxit --events email.delivered,email.bounced,email.receivedPayloads
Envelope: id, type, created_at, workspace_id, data. Native delivery/bounce data: email_id, message_id, from, to, provider_status. Incoming data: inbox_id, uid, uid_validity, address, message_id. Fetch message bodies separately.
{"id":"EVENT_UUID","type":"email.received","created_at":"2026-10-23T12:00:00Z","workspace_id":"WORKSPACE_UUID","data":{"inbox_id":"INBOX_UUID","uid":"42","uid_validity":"123456","address":"hello@mail.yourbrand.com","message_id":"<reply@example.com>"}}Verify signatures
Use the unmodified raw request Buffer before parsing JSON. Headers: webhook-id, webhook-timestamp, webhook-signature. Sign id.timestamp.rawBody with HMAC-SHA256 using the secret as a UTF-8 string. Enforce a five-minute window, then persist/deduplicate event IDs.
import {createHmac, timingSafeEqual} from 'node:crypto';
export function verify(rawBody, headers, secret) {
const id = headers['webhook-id'];
const time = headers['webhook-timestamp'];
const signature = headers['webhook-signature'];
if (!id || !/^\d+$/.test(time || '') || !signature) return false;
if (Math.abs(Date.now() / 1000 - Number(time)) > 300) return false;
const hex = createHmac('sha256', secret)
.update(id + '.' + time + '.').update(rawBody).digest('hex');
const expected = Buffer.from('v1=' + hex);
const actual = Buffer.from(signature);
return actual.length === expected.length && timingSafeEqual(actual, expected);
}
// After verification: persist/deduplicate event.id, enqueue work, return 2xx.Retries
At-least-once delivery: non-2xx/network failures retry up to eight total attempts, exponential delays from 30 seconds capped at one hour. IDs stay stable; ordering is not guaranteed. Acknowledge only after durable acceptance. GET /webhooks includes the latest 100 delivery records.
inboxit webhooks list
inboxit webhooks retry --id DELIVERY_UUIDDisable and rotate
DELETE disables an endpoint and cancels queued deliveries; an in-flight request may arrive. No update/rotation endpoint exists. Create a replacement, configure its secret, then disable the old endpoint. Deduplicate during overlap.