JSPM

  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 329
  • Score
    100M100P100Q100182F
  • License MIT

Package Exports

  • @keystrokehq/sendgrid
  • @keystrokehq/sendgrid/_official
  • @keystrokehq/sendgrid/_runtime
  • @keystrokehq/sendgrid/alerts
  • @keystrokehq/sendgrid/api-keys
  • @keystrokehq/sendgrid/client
  • @keystrokehq/sendgrid/connection
  • @keystrokehq/sendgrid/domains
  • @keystrokehq/sendgrid/email-validation
  • @keystrokehq/sendgrid/events
  • @keystrokehq/sendgrid/mail-send
  • @keystrokehq/sendgrid/marketing-contacts
  • @keystrokehq/sendgrid/marketing-customfields
  • @keystrokehq/sendgrid/marketing-lists
  • @keystrokehq/sendgrid/marketing-segments
  • @keystrokehq/sendgrid/marketing-singlesends
  • @keystrokehq/sendgrid/schemas
  • @keystrokehq/sendgrid/sender-identities
  • @keystrokehq/sendgrid/senders
  • @keystrokehq/sendgrid/stats
  • @keystrokehq/sendgrid/suppressions
  • @keystrokehq/sendgrid/templates
  • @keystrokehq/sendgrid/user-account
  • @keystrokehq/sendgrid/verification
  • @keystrokehq/sendgrid/webhooks/event
  • @keystrokehq/sendgrid/webhooks/parse

Readme

@keystrokehq/sendgrid

Official Keystroke integration for SendGrid (Twilio) — transactional + marketing email, templates, contacts, lists, segments, suppressions, deliverability, and webhook helpers.

This package follows the standard Keystroke official integration authoring pattern. The root entrypoint is intentionally empty; use explicit subpaths.


Install

pnpm add @keystrokehq/sendgrid

Connect

SendGrid authenticates with a single API key. Create one in the SendGrid console (Settings → API Keys) — we recommend a Restricted Access key with only the scopes your workflows need.

import { sendgrid, type SendGridCredentials } from '@keystrokehq/sendgrid/connection';

const credentials: SendGridCredentials = {
  SENDGRID_API_KEY: 'SG.xxx...',
  // Optional:
  SENDGRID_SUBUSER: 'acme-eu',          // adds `on-behalf-of: acme-eu` header
  SENDGRID_ACCOUNT_REGION: 'eu',        // default: 'global'
  SENDGRID_EVENT_WEBHOOK_PUBLIC_KEY: '-----BEGIN PUBLIC KEY-----\n…\n-----END PUBLIC KEY-----',
  SENDGRID_INBOUND_PARSE_TOKEN: 'token-abc',
};

void credentials;
void sendgrid;

Fields

Field Required Purpose
SENDGRID_API_KEY yes Full or restricted API key. Must start with SG..
SENDGRID_SUBUSER no Username of a subuser; sent as on-behalf-of on every request.
SENDGRID_ACCOUNT_REGION no global (default) or eu. Controls the base URL (api.sendgrid.com vs api.eu.sendgrid.com).
SENDGRID_EVENT_WEBHOOK_PUBLIC_KEY no Ed25519 public key for verifying Event Webhook deliveries. Fetch with getSignedPublicKey, store when enabling signing.
SENDGRID_INBOUND_PARSE_TOKEN no Keystroke-minted shared secret embedded in the Inbound Parse receiver URL.

Quickstart

import { sendEmail } from '@keystrokehq/sendgrid/mail-send';

void sendEmail;
import { triggers } from '@keystrokehq/sendgrid/triggers';

const onBounce = triggers.bounce({
  name: 'escalate-hard-bounces',
  filter: (event) => event.type === 'hard',
  transform: (event) => ({ email: event.email, reason: event.reason }),
});

void onBounce;

Public surface

End-user authoring imports

Import path Exports
@keystrokehq/sendgrid/mail-send sendEmail, createBatchId, validateBatchId, cancelOrPauseScheduledSend, updateScheduledSend, deleteScheduledSend, listScheduledSends, getScheduledSend
@keystrokehq/sendgrid/templates Transactional templates + versions CRUD + activate
@keystrokehq/sendgrid/marketing-contacts Marketing Contacts v3: upsert, search, batch, count, imports, exports, field definitions
@keystrokehq/sendgrid/marketing-lists Marketing Lists v3 CRUD + contact count + remove-contacts
@keystrokehq/sendgrid/marketing-segments Marketing Segments v2 CRUD + refresh + parent-filter
@keystrokehq/sendgrid/marketing-singlesends Single Sends CRUD + schedule + stats + test sends
@keystrokehq/sendgrid/marketing-customfields Marketing custom field definition CRUD
@keystrokehq/sendgrid/senders Marketing senders CRUD
@keystrokehq/sendgrid/sender-identities Verified sender identity CRUD + resend
@keystrokehq/sendgrid/suppressions Global suppressions, groups, bounces, blocks, invalid emails, spam reports
@keystrokehq/sendgrid/email-validation Single + bulk email validation (add-on gated)
@keystrokehq/sendgrid/stats Global, category, automation, mailbox-provider stats + engagement-quality scores
@keystrokehq/sendgrid/user-account Profile, account info, scopes, credit balance
@keystrokehq/sendgrid/alerts Alert CRUD
@keystrokehq/sendgrid/domains Authenticated domain read + validate
@keystrokehq/sendgrid/api-keys API key CRUD
@keystrokehq/sendgrid/webhooks/event Event Webhook configuration, signed-key fetch, signature toggle, test
@keystrokehq/sendgrid/webhooks/parse Inbound Parse configuration + stats
@keystrokehq/sendgrid/triggers 12 direct-binding webhook helpers

Support imports

Import path Exports
@keystrokehq/sendgrid/connection sendgrid credential set + SendGridCredentials type
@keystrokehq/sendgrid/client createSendGridClient, SendGridError, isSendGridError
@keystrokehq/sendgrid/schemas All Zod v4 schemas — input/output shapes for every resource
@keystrokehq/sendgrid/events Event-name constants + per-event payload schemas
@keystrokehq/sendgrid/verification verifySendGridEventWebhookRequest, verifyInboundParseRequest, parseSendGridEventWebhookBody

Hidden repo-internal imports (do not use in end-user code)

  • @keystrokehq/sendgrid/_official
  • @keystrokehq/sendgrid/_runtime

Sending email

import { sendEmail } from '@keystrokehq/sendgrid/mail-send';

void sendEmail;

The Mail Send operation accepts the full v3 body: multiple personalizations, dynamic template substitution, attachments, categories, customArgs, sandbox mode, and sendAt for scheduled sends. Pass a batchId to later cancel or pause messages.

Marketing: contacts, lists, segments, single sends

import { upsertContacts } from '@keystrokehq/sendgrid/marketing-contacts';
import { createList } from '@keystrokehq/sendgrid/marketing-lists';
import { createSegment } from '@keystrokehq/sendgrid/marketing-segments';
import { createSingleSend, scheduleSingleSend } from '@keystrokehq/sendgrid/marketing-singlesends';

void upsertContacts;
void createList;
void createSegment;
void createSingleSend;
void scheduleSingleSend;

Suppressions

One barrel export covers global, group, bounce, block, invalid, and spam suppressions:

import {
  addGlobalSuppressions,
  createSuppressionGroup,
  listBounces,
  deleteSpamReport,
} from '@keystrokehq/sendgrid/suppressions';

void addGlobalSuppressions;
void createSuppressionGroup;
void listBounces;
void deleteSpamReport;

Webhooks

Event Webhook (signed, Ed25519)

Configure via the REST helpers, then verify deliveries with the verification helpers:

import {
  createEventWebhook,
  getSignedPublicKey,
  toggleWebhookSignature,
} from '@keystrokehq/sendgrid/webhooks/event';
import { verifySendGridEventWebhookRequest } from '@keystrokehq/sendgrid/verification';
import { triggers } from '@keystrokehq/sendgrid/triggers';

void createEventWebhook;
void getSignedPublicKey;
void toggleWebhookSignature;
void verifySendGridEventWebhookRequest;
void triggers.delivered;
void triggers.open;
void triggers.groupUnsubscribe;

IMPORTANT: SendGrid signs the concatenation of the X-Twilio-Email-Event-Webhook-Timestamp header value and the raw request body bytes. Your HTTP surface must preserve the raw body — do not JSON-reparse and re-serialize before verifying.

Inbound Parse

import { createParseSetting } from '@keystrokehq/sendgrid/webhooks/parse';
import { verifyInboundParseRequest } from '@keystrokehq/sendgrid/verification';
import { triggers } from '@keystrokehq/sendgrid/triggers';

void createParseSetting;
void verifyInboundParseRequest;
void triggers.inboundParseReceived;

SendGrid does not sign Inbound Parse payloads. Verification uses a Keystroke-minted token embedded in the receiver URL (plus an optional IP allowlist). Rotate the token periodically.


Caveats

  • No OAuth. SendGrid v3 only supports API-key auth.

  • Apple Mail Privacy Protection. open events now carry sg_machine_open: true when the open is an Apple MPP cache-fetch. Filter on this flag or your workflows will trigger on every Apple Mail user.

  • One-click unsubscribe (RFC 8058). Required by major inbox providers for bulk senders. Set List-Unsubscribe-Post: List-Unsubscribe=One-Click in your headers on sendEmail.

  • Apple MPP + bounce classification. bounce events include bounce_classification — use it to distinguish reputation damage from mailbox-full soft bounces.

  • Plan-gated endpoints. stats.getEngagementQualityScores requires Pro+. /messages (Email Activity add-on) and reseller endpoints also 402/403 on most tenants. The client surfaces these as SendGridError with kind: 'forbidden' / 'auth'.

  • Region split. An API key scoped to global cannot act on eu data and vice versa. Set SENDGRID_ACCOUNT_REGION correctly at connect time.

  • Legacy /contactdb/*, Legacy Marketing Campaigns, Designs API, Reverse DNS, IP pools, Subusers, Teammates, SSO, Mail/Tracking Settings. Not wrapped in phase 1. Fall back to the typed client for these:

    import { createSendGridClient } from '@keystrokehq/sendgrid/client';
    
    void createSendGridClient;
  • Phase 1 coverage. This package ships ~150 operations focused on Mail Send, Templates, Marketing Contacts/Lists/Segments/Single Sends/CustomFields, Suppressions, Senders, Stats, Email Validation, User Account, Alerts, API Keys, Authenticated Domains, and the Event + Inbound Parse webhook config surface.


Verification helpers

verifySendGridEventWebhookRequest and verifyInboundParseRequest are pure functions — they accept { rawBody, signature, timestamp, publicKeyPem } (Event Webhook) or { path, expectedToken, sourceIp?, allowedIps? } (Inbound Parse) and return a boolean. They have no side effects and no I/O, so they are safe to call from any Keystroke runtime surface.


License

MIT © Keystroke