InboxRider
Home Docs Pricing Log in
Home/ Docs/ Webhooks
Developers

Webhooks

Signed HTTPS callbacks when new inbound mail arrives.

Overview API reference Webhooks

Manage endpoints with an API key that has webhooks:manage, or in the app under Settings → Company → API & integrations. These are separate from Slack / Teams notification destinations under Automations.

1. Register an endpoint

POST /api/v1/webhooks
Authorization: Bearer ir_…
Content-Type: application/json

{
  "url": "https://your-app.example.com/hooks/inboxrider",
  "events": ["message.inbound"]
}

The response includes secret once (whsec_…). Store it securely.

  • List: GET /api/v1/webhooks
  • Deactivate: DELETE /api/v1/webhooks/:id

URL rules

  • HTTPS only
  • Localhost, private networks, link-local, and cloud metadata hosts are rejected
  • DNS answers are checked so the host cannot resolve to a private address

2. Event: message.inbound

Fired when a new inbound message is ingested (not a duplicate Message-ID, not a historical import). Delivery failures never roll back message storage.

{
  "id": "evt_<messageId>",
  "type": "message.inbound",
  "createdAt": "2026-09-07T12:00:00.000Z",
  "organizationId": "org_…",
  "data": {
    "messageId": "msg_…",
    "conversationId": "conv_…",
    "inboxId": "inb_…",
    "channelId": "ch_…",
    "fromEmail": "alex@acme.com",
    "fromName": "Alex",
    "toEmails": ["sales@example.com"],
    "subject": "Re: Quick question",
    "body": "<p>…</p>",
    "internetMessageId": "<…@mail.gmail.com>",
    "inReplyTo": "<…>",
    "createdAt": "…"
  }
}

3. Verify signatures

HeaderValue
X-InboxRider-Eventmessage.inbound
X-InboxRider-Event-Idevt_…
X-InboxRider-TimestampUnix seconds
X-InboxRider-Signaturesha256=<hex>

Canonical string:

{timestamp}.{rawRequestBody}
  1. Read the raw body bytes (do not re-serialize JSON).
  2. Compute HMAC-SHA256(secret, "{timestamp}.{rawBody}") as hex.
  3. Compare to the signature with constant-time equality.
  4. Reject if |now − timestamp| > 300 seconds.

Node.js example

import crypto from "crypto";

function verifyInboxRiderWebhook({ rawBody, timestamp, signature, secret }) {
  const age = Math.abs(Date.now() / 1000 - Number(timestamp));
  if (!Number.isFinite(age) || age > 300) return false;

  const expected =
    "sha256=" +
    crypto.createHmac("sha256", secret).update(`${timestamp}.${rawBody}`).digest("hex");

  const a = Buffer.from(expected);
  const b = Buffer.from(String(signature || ""));
  if (a.length !== b.length) return false;
  return crypto.timingSafeEqual(a, b);
}

4. Retries

AttemptDelay
1immediate
2~30s
3~2m
4~10m
5~30m

Return 2xx quickly; do heavy work asynchronously. Treat deliveries as idempotent on id / data.messageId.

5. Handler checklist

  1. Verify signature and timestamp skew.
  2. Confirm type === "message.inbound".
  3. Deduplicate on event / message id.
  4. Optionally load the thread with GET /api/v1/conversations/:id — see the API reference.
curl -sS https://api.inboxrider.com/api/v1/webhooks \
  -H "Authorization: Bearer ir_…" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://your-app.example.com/hooks/inboxrider",
    "events": ["message.inbound"]
  }'
© 2026 InboxRider
Docs API Privacy Terms