# SendGrid Event Webhook

> SendGrid event webhook with delivery, engagement, and compliance events.

- Name: `sendgrid-event-webhook`
- Categories: sendgrid
- Detail page: https://open-types.dev/types/sendgrid-event-webhook

## Install

```bash
# Types only
npx shadcn add @open-types/sendgrid-event-webhook

# Types + Zod v4 validators
npx shadcn add @open-types/sendgrid-event-webhook-zod

# Types + real-world examples
npx shadcn add @open-types/sendgrid-event-webhook-examples
```

## Types

```typescript
export type SendGridEventType =
  | "processed"
  | "dropped"
  | "delivered"
  | "deferred"
  | "bounce"
  | "open"
  | "click"
  | "spam_report"
  | "unsubscribe"
  | "group_unsubscribe"
  | "group_resubscribe";

export interface SendGridEvent {
  email: string;
  timestamp: number;
  event: SendGridEventType;
  sg_event_id: string;
  sg_message_id?: string;
  category?: string | string[];
  reason?: string;
  url?: string;
  useragent?: string;
  ip?: string;
}
```

## Zod validator

```typescript
import * as z from "zod";
import type { SendGridEvent, SendGridEventType } from "../types/sendgrid-event-webhook";

export const sendGridEventTypeSchema = z.enum([
  "processed",
  "dropped",
  "delivered",
  "deferred",
  "bounce",
  "open",
  "click",
  "spam_report",
  "unsubscribe",
  "group_unsubscribe",
  "group_resubscribe",
]) satisfies z.ZodType<SendGridEventType>;

export const sendGridEventSchema = z.object({
  email: z.string(),
  timestamp: z.number(),
  event: sendGridEventTypeSchema,
  sg_event_id: z.string(),
  sg_message_id: z.string().optional(),
  category: z.union([z.string(), z.array(z.string())]).optional(),
  reason: z.string().optional(),
  url: z.string().optional(),
  useragent: z.string().optional(),
  ip: z.string().optional(),
}) satisfies z.ZodType<SendGridEvent>;

export type { SendGridEvent, SendGridEventType } from "../types/sendgrid-event-webhook";
```

## Examples

```typescript
// Source: https://docs.sendgrid.com/for-developers/tracking-events/event
// Captured: 2026-05
import type {
  SendGridEventType,
  SendGridEvent,
} from "../types/sendgrid-event-webhook";

export const sendGridEventTypeExamples = {
  processed: "processed",
  dropped: "dropped",
  delivered: "delivered",
  deferred: "deferred",
  bounce: "bounce",
  open: "open",
  click: "click",
  spamReport: "spam_report",
  unsubscribe: "unsubscribe",
  groupUnsubscribe: "group_unsubscribe",
  groupResubscribe: "group_resubscribe",
} as const satisfies Record<string, SendGridEventType>;

const baseEvent = {
  email: "customer@example.com",
  timestamp: 1712948400,
  event: "processed",
  sg_event_id: "sg_event_id_abc123",
  sg_message_id: "filter0123.0001.5BB9D6E0.0",
} as const satisfies SendGridEvent;

export const sendGridEventExamples = {
  processed: baseEvent,
  delivered: { ...baseEvent, event: "delivered", sg_event_id: "sg_event_delivered_001" } satisfies SendGridEvent,
  bounce: {
    ...baseEvent,
    event: "bounce",
    sg_event_id: "sg_event_bounce_001",
    reason: "550 5.1.1 The email account that you tried to reach does not exist",
  } satisfies SendGridEvent,
  click: {
    ...baseEvent,
    event: "click",
    sg_event_id: "sg_event_click_001",
    url: "https://open-types.dev/welcome",
    useragent: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)",
    ip: "203.0.113.42",
  } satisfies SendGridEvent,
  open: {
    ...baseEvent,
    event: "open",
    sg_event_id: "sg_event_open_001",
    useragent: "Mozilla/5.0 (iPhone; CPU iPhone OS 17_3 like Mac OS X)",
    ip: "198.51.100.21",
  } satisfies SendGridEvent,
  unsubscribe: {
    ...baseEvent,
    event: "unsubscribe",
    sg_event_id: "sg_event_unsub_001",
    category: "marketing",
  } satisfies SendGridEvent,
  spamReport: {
    ...baseEvent,
    event: "spam_report",
    sg_event_id: "sg_event_spam_001",
    category: ["marketing", "newsletter"],
  } satisfies SendGridEvent,
  dropped: {
    ...baseEvent,
    event: "dropped",
    sg_event_id: "sg_event_drop_001",
    reason: "Invalid SMTPAPI header",
  } satisfies SendGridEvent,
} as const;
```
