Create or update a contact
const url = 'https://api.tryletterhead.com/api/v3/contacts';const options = { method: 'POST', headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'}, body: '{"api":true,"email":"[email protected]","firstName":"Michael","lastName":"Jones","tags":["amazing-contact","engaged"],"customFields":{"favoriteColor":"blue","lifetimeValue":250},"source":"website-signup"}'};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request POST \ --url https://api.tryletterhead.com/api/v3/contacts \ --header 'Authorization: Bearer <token>' \ --header 'Content-Type: application/json' \ --data '{ "api": true, "email": "[email protected]", "firstName": "Michael", "lastName": "Jones", "tags": [ "amazing-contact", "engaged" ], "customFields": { "favoriteColor": "blue", "lifetimeValue": 250 }, "source": "website-signup" }'Creates a company-level contact, or updates the existing contact if one with the same email already exists (an upsert).
- If no contact with the given
emailexists, a new contact is created and the response is201 Created. - If a contact with that
emailalready exists, its profile is updated with the fields in the request body and the response is200 OK. - If a
channelis supplied (see below), an already-existing contact’s profile is not overwritten — the contact is simply subscribed to that channel.
Custom fields
Pass a customFields object to set values on the contact’s custom fields. Each key is the name of a custom field you’ve defined for your company, and the value is coerced to that field’s configured type (text, number, boolean, or date).
{
"email": "[email protected]",
"customFields": {
"favoriteColor": "blue",
"lifetimeValue": 250
}
}
Notes:
- Each key must match a custom field that already exists for your company. Unknown field names are rejected.
- Keys beginning with
__lh.are reserved for Letterhead’s system-managed fields and cannot be set. customFieldsis optional. Omit it to create a contact without setting any custom field values.
Channel subscription
Provide a channel (a channel slug) to subscribe the contact to that channel at creation time. If a company-level contact with the same email already exists, its existing profile is left untouched and the contact is simply subscribed to the channel. Omit channel to create the contact at the company level only.
Source
The optional source records where the contact came from — for example, the name of the integration that created it. It is set once on the contact and is not overwritten by later updates. A create without a source is recorded as a hand-entered manual contact.
Authorizations
Section titled “Authorizations ”Request Body required
Section titled “Request Body required ”object
Required. Set to true to authenticate with an API key.
The contact’s email address. Identifies the contact for the upsert.
The contact’s first name.
The contact’s last name.
Tags to apply to the contact.
Values for your company’s custom fields, keyed by field name. See below.
object
Origin label for where the contact came from. Recorded once and never overwritten. Defaults to manual when omitted. See below.
Example
{ "api": true, "firstName": "Michael", "lastName": "Jones", "tags": [ "amazing-contact", "engaged" ], "customFields": { "favoriteColor": "blue", "lifetimeValue": 250 }, "source": "website-signup"}Responses
Section titled “ Responses ”Existing contact updated
New contact created
Still can’t find what you need? Contact support.