latestOpenAPI 3.1.02026-08-194237902.5 MB

563848e0ecc0

Send Grid Webhook Resource

Receive SendGrid delivery-status events for outreaches

Accepts a batch of email delivery-status events (delivered, bounced, opened, clicked, dropped, deferred, etc.) posted by SendGrid's Event Webhook and applies each one to the matching outreach email record. Configure this URL in SendGrid's Event Webhook settings for outreach sender identities; use the sibling POST /outreach/sendgrid/webhook/incoming-parse endpoint instead for inbound reply emails. The request body must be a non-empty JSON array of event objects; each event should carry outreach context (tenantId/emailId/outreachId) as top-level fields or nested under a custom_args object, and falls back to matching by sg_message_id alone when that context is absent. This call returns 200 immediately after starting processing: the delivery-status updates and the best-effort audit copy (raw payload to Cloud Storage plus a WebhookRawBlob record) all happen asynchronously in the background after the response is sent, so a 200 does not guarantee any individual event was actually applied. A body that is not a JSON array, an empty array, or an array with no event carrying a usable sg_message_id/event pair is not treated as an error - it still returns 200 and applies nothing. This is a public endpoint that does not require authentication; no tenant-id header is used.

post/outreach/sendgrid/webhook/email-status

Headers

tenant-idstring required

Tenant ID

Request body

emailstring

Recipient email address the event applies to.

timestampstring

Unix epoch seconds, as a string, at which SendGrid recorded the event; see getEventTime() to convert to an Instant.

eventstring

SendGrid event type, e.g. delivered, open, click, bounce, dropped, deferred, spamreport, unsubscribe, group_unsubscribe, group_resubscribe.

categorystring

Category tag attached to the originating send, if one was set.

sgMessageIdstring

SendGrid's message identifier for the originating send, delivered on the wire as sg_message_id; used to correlate this event back to the outreach email that generated it.

smtp-idstring

The smtp-id header of the originating message, if present.

responsestring

Raw SMTP response text from the receiving mail server; present on delivered, bounce, and deferred events.

attemptstring

Delivery attempt number, as a string; present on deferred events.

statusstring

SMTP status/response code; present on bounce and deferred events.

reasonstring

Human-readable reason for the event; present on bounce, dropped, and deferred events.

typestring

Bounce classification, e.g. bounce vs blocked; present on bounce events.

eventTimestring date-time

Example request

[
  {
    "email": "jane.doe@example-clinic.com",
    "timestamp": "1700000000",
    "event": "delivered",
    "category": "credentialing-outreach",
    "sgMessageId": "14c5d75ce93.filterdrecv.recvd-1-B.0",
    "smtp-id": "<14c5d75ce93.dfd.64b469@ismtpd-555>",
    "response": "250 2.0.0 OK",
    "attempt": "1",
    "status": "5.1.1",
    "reason": "550 5.1.1 The email account does not exist",
    "type": "bounce",
    "eventTime": "2022-03-10T16:15:50Z"
  }
]

Response

Processing was started (or intentionally skipped for an empty/invalid batch). The JSON body is a bare string, not an object: "Processing N email status update events" when at least one event carried a usable sg_message_id/event pair (updates continue in the background); "No events to process" when the body was not a non-empty JSON array; or "No valid events to process" when it was an array but no event carried a usable sg_message_id/event pair. None of these are errors.

string required