X Enterprises
fastify-xemail

contacts-add

Add or update a contact in SendGrid Marketing using the upsert API.

addContact

Add or update a contact in SendGrid Marketing. This is an upsert — if a contact with the given email already exists it will be updated. Accepts both camelCase (firstName) and snake_case (first_name) field names.

Note: SendGrid contact upserts are processed asynchronously. The returned jobId can be used to check import status via the SendGrid API.

Signature

fastify.xEmail.addContact(
  email: string,
  data?: ContactData,
  listIds?: string[]
): Promise<{ success: boolean; jobId: string; email: string }>

interface ContactData {
  firstName?: string;
  first_name?: string;
  lastName?: string;
  last_name?: string;
  customFields?: Record<string, string | number>;
}

Params

NameTypeRequiredDescription
emailstringYesContact email address.
dataContactDataNoContact metadata. Accepts firstName/lastName or first_name/last_name.
listIdsstring[]NoArray of SendGrid list IDs to add the contact to.

Returns

Promise<{ success: boolean; jobId: string; email: string }>

PropertyTypeDescription
successbooleanAlways true on resolved promise.
jobIdstringSendGrid async job ID for the import operation.
emailstringThe contact email that was upserted.

Throws

  • [xEmail] 'email' (string) is required for addContact().
  • [xEmail] Failed to add contact: <reason> — SendGrid API error.

Examples

Basic — add a subscriber after signup

fastify.post("/newsletter/subscribe", async (request, reply) => {
  const { email, firstName, lastName } = request.body;

  const result = await fastify.xEmail.addContact(
    email,
    { firstName, lastName },
    [process.env.NEWSLETTER_LIST_ID]
  );

  return { subscribed: result.success, jobId: result.jobId };
});

Realistic — sync user profile on update

fastify.put("/users/:id/profile", async (request) => {
  const user = await db.users.update(request.params.id, request.body);

  await fastify.xEmail.addContact(
    user.email,
    {
      firstName: user.firstName,
      lastName: user.lastName,
      customFields: {
        w1_T: user.plan,          // custom field ID for plan
        w2_N: user.companyName,   // custom field ID for company
      },
    }
  );

  return user;
});

See Also

AI Context

package: "@xenterprises/fastify-xemail"
method: fastify.xEmail.contactsAdd(contactData, listIds?)
use-when: Add or upsert a contact in SendGrid Marketing Contacts — async operation (returns job ID)
params: contactData ({ email (required), firstName, lastName, ...custom fields }), listIds (string[])
returns: Promise<{ jobId: string }>
Copyright © 2026