Joint session with Vercel: How to build intelligent storefronts (May 15th)

How to send email notifications on new Sanity documents using webhooks?

42 repliesLast updated: Dec 2, 2025

Hey everyone. Anyone knows any good method to use webhooks to handle email notifications when a new document is created in Sanity? I’m collecting form submissions and need to have some sort of notification whenever a new one comes in.
AI Update

For handling email notifications when new documents are created in Sanity, webhooks are your best bet. They're a stable, production-ready feature that's perfect for triggering external actions like sending emails when form submissions come in.

Setting Up Webhooks

You can create webhooks in your project's API settings at sanity.io/manage. Here's what you need to configure:

Basic setup:

The webhooks documentation has full details on all configuration options including projections (to customize the payload), HTTP headers, and more.

Verifying Webhook Signatures

Always verify the signature to ensure requests are actually coming from Sanity. Sanity includes an X-Sanity-Signature header with each webhook request, which you should validate using the secret you configured.

If you're using Next.js, the next-sanity package includes helpful utilities:

import { parseBody } from 'next-sanity/webhook'

export async function POST(req: Request) {
  const signature = req.headers.get('x-sanity-signature')
  const body = await req.text()
  
  const { isValidSignature, body: payload } = await parseBody(
    body,
    signature,
    process.env.SANITY_WEBHOOK_SECRET
  )
  
  if (!isValidSignature) {
    return new Response('Invalid signature', { status: 401 })
  }
  
  // Send your email notification here
  await sendEmail({
    to: 'your@email.com',
    subject: 'New Form Submission',
    body: `New submission: ${JSON.stringify(payload)}`
  })
  
  return new Response('OK', { status: 200 })
}

For other environments, you can use the standalone @sanity/webhook toolkit:

import { isValidSignature, SIGNATURE_HEADER_NAME } from '@sanity/webhook'

export async function handleWebhook(req) {
  const signature = req.headers[SIGNATURE_HEADER_NAME]
  const body = await req.text()
  
  if (!isValidSignature(body, signature, process.env.SANITY_WEBHOOK_SECRET)) {
    return { statusCode: 401, body: 'Invalid signature' }
  }
  
  const payload = JSON.parse(body)
  // Send email notification
  // ...
  
  return { statusCode: 200, body: 'OK' }
}

Example: Sending Email with a Webhook

Here's a complete example using a Next.js API route with SendGrid:

import { parseBody } from 'next-sanity/webhook'
import sgMail from '@sendgrid/mail'

sgMail.setApiKey(process.env.SENDGRID_API_KEY!)

export async function POST(req: Request) {
  const signature = req.headers.get('x-sanity-signature')
  const body = await req.text()
  
  const { isValidSignature, body: submission } = await parseBody(
    body,
    signature,
    process.env.SANITY_WEBHOOK_SECRET
  )
  
  if (!isValidSignature) {
    return new Response('Invalid signature', { status: 401 })
  }
  
  await sgMail.send({
    to: 'your@email.com',
    from: 'notifications@yourdomain.com',
    subject: 'New Form Submission',
    text: `
      New submission received:
      Name: ${submission.name}
      Email: ${submission.email}
      Message: ${submission.message}
    `
  })
  
  return new Response('OK', { status: 200 })
}

Alternative: Sanity Functions (Experimental)

If you'd prefer not to manage your own endpoint, Sanity Functions are an option worth knowing about. They're serverless functions that run directly on Sanity's infrastructure and can react to document changes.

However, note that Functions are currently marked as experimental, meaning the APIs are subject to change. For production use cases like yours, webhooks are the more stable choice.

If you want to explore Functions anyway, they work by defining a blueprint configuration and deploying functions that respond to document events. The setup involves initializing blueprints (npx sanity blueprints init) and configuring document functions to trigger on create/update/delete events.

Webhook Best Practices

Check out the webhook best practices guide for more tips on building robust webhook handlers.

Show original thread
42 replies

Was this answer helpful?

Sanity – Build the way you think, not the way your CMS thinks

Sanity is the developer-first content operating system that gives you complete control. Schema-as-code, GROQ queries, and real-time APIs mean no more workarounds or waiting for deployments. Free to start, scale as you grow.

Related contributions