SendGrid

SendGrid (Twilio SendGrid) is an email delivery and marketing platform. This destination syncs your Jitsu users to SendGrid as marketing contacts and manages their list membership, using the Marketing Contacts API.

How it works

SendGrid identifies contacts by email address. Jitsu maps events to SendGrid contacts as follows:

EventWhat Jitsu does
identifyUpserts the contact (create or update) and reconciles its list membership.
track / page / screenUpdates the existing contact's fields (never creates a contact).
groupUpdates the existing contact with the group id and group traits as group_* fields.

Contact upserts in SendGrid are asynchronous — the API accepts the request (HTTP 202) and processes it in the background, so changes may take a moment to appear in the dashboard.

identify

Each identify() upserts a contact via PUT /v3/marketing/contacts:

  • Email is read from traits.email (falling back to context.traits.email). Events without an email are skipped.
  • First / last name come from traits.firstName / traits.lastName, or are split from traits.name.
  • The Jitsu userId and anonymousId are stored as the custom fields jitsu_user_id and jitsu_anonymous_id. (Email is kept as the contact's only SendGrid identifier — SendGrid rejects an upsert that omits any identifier a matched contact already has, so userId/anonymousId are not used as SendGrid identifiers.)
  • All other traits are stored as SendGrid custom fields. SendGrid requires custom fields to be defined before use and references them by an internal field ID, so Jitsu automatically creates a Text field definition for each new trait key it sees and maps values to the right IDs. Traits whose names match a writable SendGrid reserved field (city, country, postal_code, …) are written to that reserved field instead.
  • The contact's list membership is reconciled to match the configured set.

A repeated identify() for the same email updates the existing contact rather than creating a duplicate.

Other events

track, page, screen and group events update an existing contact but never create one. Because the SendGrid upsert would otherwise create a contact, Jitsu first checks that the contact exists (via the search API) and skips the event if it doesn't. An update happens only when the event carries fields explicitly set on it (typically added by a transformation function) — ambient identify traits echoed on the event are ignored so the contact isn't rewritten on every event.

Lists

Set Lists in the destination config to a comma-separated list of list names (not IDs) — for example Customers, Beta. Jitsu resolves each name to a SendGrid Marketing list, creating any that don't exist yet. Leave it empty to add contacts without a list.

You can override the lists per event by setting a sendgridLists trait (also comma-separated names) from a function:

export default async function (event) {
  if (event.traits?.plan === "enterprise") {
    event.traits.sendgridLists = "Customers, Enterprise";
  }
  return event;
}

Membership is reconciled

On each identify(), Jitsu makes the contact's membership match the desired set. Lists it previously added that are no longer listed are removed. For example, if a function returns A, B on one event and B, C on the next, the contact is removed from A, kept in B, and added to C.

To do this safely, the connector records which lists it added in a custom field named jitsu_managed_lists — so it only ever removes lists it added, never ones you added manually or via another tool. There's no separate state stored in Jitsu; the record lives on the contact.

Notes:

  • Reconciliation runs only when a desired set is provided for the event — i.e. the sendgridLists trait is present, or the destination has configured Lists. An event with neither leaves membership untouched.
  • Setting sendgridLists to an empty string explicitly clears the connector-managed lists.
  • Only identify() manages membership; track / page / group events never change it.

Matching events by userId

SendGrid matches contacts by email. Enable Resolve email from userId to have every identify() cache a userId → email mapping, so later track / page / group events that carry only a userId can be matched to the contact via that cache. The cache is only populated from identify() calls seen after the flag is enabled. If neither an email nor a cached userId resolves, the event is skipped.

Notes

  • Unsubscribe / suppression state is managed separately in SendGrid (suppression groups) and is not set by this destination.
  • Contact upserts are processed asynchronously by SendGrid and can take up to a minute or two to appear. The first event that introduces a brand-new custom field is retried once (a just-created field definition isn't usable immediately); it lands automatically on the retry.
  • SendGrid's free tier is a time-limited trial; a paid Marketing Campaigns plan is required for ongoing use.

Configuration