Email Webhook API

Get notified the moment an email arrives.

InboxParse pushes email events to your endpoint in real time. HMAC-signed, retry-safe, and fired the moment an email arrives or finishes AI processing.

Register a webhook endpoint
# Create a webhook
curl -X POST https://inboxparse.com/api/v1/webhooks \
  -H "Authorization: Bearer ip..." \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://yourapp.com/webhooks/email",
    "events": ["email.received", "email.ai_processed"],
    "description": "New email pipeline trigger"
  }'

# Response
{
  "data": {
    "id": "wh_01jxxx",
    "url": "https://yourapp.com/webhooks/email",
    "signing_secret": "whsec_xxxxxxxxxxxxxxxxxxx",
    "events": ["email.received", "email.ai_processed"],
    "created_at": "2026-03-07T16:00:00Z"
  }
}

Real-time delivery

Webhook fires within seconds of a new email arriving. No polling loops. No cron jobs.

HMAC-signed payloads

Every request includes an X-Inboxparse-Signature header. Verify authenticity before processing.

Lean, ID-first payloads

The webhook body carries the event type plus message and thread IDs - fetch exactly the data you need from the API, in the format you want.

AI processing signal

email.ai_processed fires once labeling and summarization finish, so the enriched email is ready the moment you fetch it.

Test delivery endpoint

Send a test payload to your endpoint from the API or dashboard before going live.

Auto-disable protection

Webhooks are automatically paused after repeated failures to protect your pipeline. Re-enable via API.

Handle the webhook payload in your server

Copy-and-paste ready. No boilerplate.

Handle the webhook payload in your server
import { createHmac, timingSafeEqual } from "crypto"

// Next.js App Router route handler
export async function POST(req: Request) {
  const body = await req.text()
  const signature = req.headers.get("x-inboxparse-signature") ?? ""
  const secret = process.env.INBOXPARSE_WEBHOOK_SECRET!

  // 1. Verify HMAC signature
  const expected = createHmac("sha256", secret).update(body).digest("hex")
  const valid = timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(expected)
  )
  if (!valid) return new Response("Unauthorized", { status: 401 })

  // 2. Parse the event
  const event = JSON.parse(body)

  if (event.event === "email.ai_processed") {
    const { messageId } = event.data

    // 3. Fetch the AI-enriched email and route by label
    const res = await fetch(
      `https://inboxparse.com/api/v1/emails/${messageId}`,
      { headers: { Authorization: `Bearer ${process.env.INBOXPARSE_API_KEY}` } }
    )
    const { data: email } = await res.json()

    if (email.ai.labels.some((l) => l.name === "support")) {
      await createTicket(email)
    }

    // 4. Trigger downstream pipeline
    await triggerRagIngestion(email.thread_id)
  }

  return new Response("OK", { status: 200 })
}

Frequently asked questions

How are webhook payloads signed?+

Every webhook request includes an X-Inboxparse-Signature header containing an HMAC-SHA256 hash of the request body, signed with your webhook's unique signing secret. Verify this signature server-side before processing.

What happens if my endpoint is down?+

InboxParse retries failed deliveries with exponential backoff. After repeated failures, the webhook is automatically paused to protect your pipeline. You can re-enable it via the API or dashboard at any time.

What data is included in the webhook payload?+

The payload is a lean event envelope: the event type (email.received, email.sent, email.ai_processed, mailbox.synced, or mailbox.error), a timestamp, and resource IDs like messageId and threadId. Fetch the full email - clean Markdown, AI labels, summary, and suggested action - via GET /api/v1/emails/{messageId}.

React to email as it happens.

Set up your first webhook in under 2 minutes. Free plan includes webhook access.