Skip to main content
The Zoho Mail plugin handles incoming webhooks. Point your provider’s subscription URL at your Corsair HTTP handler (see Overview for setup context and the exact URL shape).
New to Corsair? See webhooks and hooks.
Zoho Mail’s webhook model differs from most providers — read before relying on it.
  • Per-account, not app-level. There is no single webhook URL you register once in the API Console for all connected mailboxes. Each mailbox owner must add the URL manually in their own Zoho Mail UI (Settings → Integrations → Developer Space → Outgoing Webhooks).
  • No API to register it — it cannot be auto-provisioned per tenant.
  • Paid plans only. Developer Space (and thus webhooks) is gated behind a paid Zoho plan.
  • Handshake + signature. The first request carries the secret in the x-hook-secret header (acknowledge with a 200). Subsequent requests are signed with x-hook-signature = base64 HMAC-SHA256 of the raw request body. Your HTTP route must verify against the raw body bytes — re-serializing parsed JSON can break verification.
For multi-tenant / free-tier setups, prefer polling: call messages.list on an interval and read the synced local DB. The plugin’s list/get endpoints upsert to the database on every call, and folders.list is wired into setupCorsair({ backfill: true }).

Webhook map

  • messages
    • received (messages.received)

HTTP handler setup

app/api/webhook/route.ts
import { processWebhook } from "corsair";
import { corsair } from "@/server/corsair";

export async function POST(request: Request) {
    const headers = Object.fromEntries(request.headers);
    const body = await request.json();
    const result = await processWebhook(corsair, headers, body);
    return result.response;
}

Events

Messages

Received

messages.received A new email was received in the mailbox Payload
NameTypeRequiredDescription
messageIdstringNo
folderIdstringNo
subjectstringNo
summarystringNo
htmlstringNo
fromAddressstringNo
toAddressstringNo
ccAddressstringNo
senderstringNo
sentDateInGMTstringNo
receivedTimestringNo
sizestring | numberNo
{
  messageId?: string,
  folderId?: string,
  subject?: string,
  summary?: string,
  html?: string,
  fromAddress?: string,
  toAddress?: string,
  ccAddress?: string,
  sender?: string,
  sentDateInGMT?: string,
  receivedTime?: string,
  size?: string | number
}
webhookHooks example
zohomail({
    webhookHooks: {
        messages: {
            received: {
                before(ctx, args) {
                    return { ctx, args };
                },
                after(ctx, response) {
                },
            },
        },
    },
})