Email Webhook API

Get notified the moment an email arrives.

InboxParse pushes parsed email events to your endpoint in real time. HMAC-signed, retry-safe, and enriched with AI labels and Markdown content.

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": ["message.received"],
    "description": "New email pipeline trigger"
  }'

# Response
{
  "data": {
    "id": "wh_01jxxx",
    "url": "https://yourapp.com/webhooks/email",
    "signing_secret": "whsec_xxxxxxxxxxxxxxxxxxx",
    "events": ["message.received"],
    "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.

Full parsed payload

The webhook body includes the parsed Markdown, AI labels, sender metadata, and thread ID. No second API call needed.

AI labels included

Category, action and sentiment already computed when your webhook fires. Start routing immediately.

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.type === "message.received") {
    const { thread_id, subject, labels } = event.data

    // 3. Route by AI label
    if (labels.category === "support") {
      await createTicket({ thread_id, subject, labels })
    }

    // 4. Trigger downstream pipeline
    await triggerRagIngestion(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 includes the parsed Markdown content, AI labels (category, action, sentiment), sender metadata, thread ID, subject line, and message timestamps. No second API call is needed to get the full context.

React to email as it happens.

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