Skip to content

Webhooks

Foyer can POST to any HTTPS endpoint when meaningful events happen in your inbox: a conversation is opened, a message is sent, a customer replies, a ticket changes state. Webhook deliveries include a signature header so you can verify the request really came from Foyer.

Configure a webhook

Webhooks are scoped to a workspace. Create one from the dashboard at Workspace → Developer → Webhooks, or via the REST API (reference):

Terminal window
curl https://api.foyersupport.com/v1/webhooks \
-H "Authorization: Bearer $FOYER_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://example.com/foyer-webhook",
"events": ["conversation.opened", "message.sent"]
}'

The response includes a signing_secret — store it. Foyer signs every delivery with HMAC-SHA256 using this secret.

Verify a delivery

Every request carries an X-Foyer-Signature header in the form t=<unix_ts>,v1=<hex_digest>. Compute HMAC_SHA256(secret, "<ts>.<body>") and compare in constant time.

import crypto from "node:crypto";
function verifyFoyerSignature(
body: string,
header: string,
secret: string,
): boolean {
const parts = Object.fromEntries(
header.split(",").map((p) => p.split("=")),
);
const expected = crypto
.createHmac("sha256", secret)
.update(`${parts.t}.${body}`)
.digest("hex");
return crypto.timingSafeEqual(
Buffer.from(expected),
Buffer.from(parts.v1),
);
}

Retries and deliverability

Failed deliveries (any non-2xx response, or a connection that times out within 10 seconds) are retried with exponential backoff for 72 hours, then moved to the dead-letter queue. Inspect failed deliveries from Workspace → Developer → Webhooks → Deliveries.

See also