Connect your users' Gmail, store every message, and get a signed event the moment new mail lands. Verify the signature, fetch the full content from one API. That's it.
No credit card · self-serve in minutes
The boring, reliable parts — OAuth, change detection, storage, signing, retries — handled. You write the part that matters.
White-label OAuth. Hand users a branded link; their mailbox connects in two clicks — your name, your colors.
Every new email becomes an HMAC-signed message.created POST. At-least-once with retries, a dead-letter queue, and idempotency.
On connect we sync the entire mailbox to your store — paginated and quiet, with no webhook flood for historical mail.
Webhooks stay thin. Pull the full message, headers, and attachment metadata on demand, authenticated with your api_key.
Sign up and spin up an organization. Your api_key and webhook signing secret are issued instantly.
Share your branded connect link. Users authorize Gmail; we set up change-watching and backfill automatically.
We POST a signed event on every new email. Verify the signature, then fetch the body from the Read API.
A thin, signed notification plus a fetch-on-demand API — the Nylas pattern. Verify in a few lines, in any language.
POST https://your-app.com/webhooks/courier-owl
X-CourierOwl-Event: message.created
X-CourierOwl-Signature: 9f86d08…
{
"type": "message.created",
"org_id": "org_8129…",
"data": { "object": {
"id": "19e77cd732…",
"from": { "email": "sender@x.com", "name": "Sender" },
"subject": "hi",
"snippet": "Hello…",
"fetch_url": "https://…/v1/orgs/…/messages/…"
} }
}import crypto from "crypto";
const expected = crypto
.createHmac("sha256", WEBHOOK_SECRET)
.update(rawBody) // the RAW request bytes
.digest("hex");
if (crypto.timingSafeEqual(
Buffer.from(sig), Buffer.from(expected))) {
// trusted — enqueue data.object.id, ack 2xx fast
}Create an account, connect a mailbox, and watch the signed events roll in.