Skip to content
Letterhead Letterhead Letterhead Help Center
Admin Tools

Create or update a contact

POST
/api/v3/contacts
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 email exists, a new contact is created and the response is 201 Created.
  • If a contact with that email already exists, its profile is updated with the fields in the request body and the response is 200 OK.
  • If a channel is 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.
  • customFields is 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.

Media type application/json
object
api

Required. Set to true to authenticate with an API key.

boolean
email
required

The contact’s email address. Identifies the contact for the upsert.

string
firstName

The contact’s first name.

string
lastName

The contact’s last name.

string
tags

Tags to apply to the contact.

Array<string>
customFields

Values for your company’s custom fields, keyed by field name. See below.

object
favoriteColor
string
lifetimeValue
integer
source

Origin label for where the contact came from. Recorded once and never overwritten. Defaults to manual when omitted. See below.

string
Example
{
"api": true,
"email": "[email protected]",
"firstName": "Michael",
"lastName": "Jones",
"tags": [
"amazing-contact",
"engaged"
],
"customFields": {
"favoriteColor": "blue",
"lifetimeValue": 250
},
"source": "website-signup"
}

Existing contact updated

New contact created

Still can’t find what you need? Contact support.