Skip to main content
POST
/
contacts
Add and update contact
curl --request POST \
  --url https://api.lemlist.com/api/contacts \
  --header 'Authorization: Basic <encoded-value>' \
  --header 'Content-Type: application/json' \
  --data '
{
  "email": "jane.smith@example.com",
  "firstName": "Jane",
  "lastName": "Smith",
  "linkedinUrl": "https://linkedin.com/in/janesmith",
  "jobTitle": "Product Manager",
  "companyDomain": "acme.com"
}
'
{
  "success": true,
  "data": {
    "_id": "ctc_Rofmb6uNGyaPNZ2ni",
    "teamId": "tea_b4rMsi2trB42WyuWP",
    "emails": [
      {
        "value": "jane.smith@example.com"
      }
    ],
    "fields": {
      "firstName": "Jane",
      "lastName": "Smith",
      "jobTitle": "Product Manager"
    },
    "ownerId": "usr_gmHgNGRcGPSTJrDbT",
    "source": "api",
    "createdAt": "2025-10-28T00:40:37.917Z",
    "createdBy": "usr_gmHgNGRcGPSTJrDbT",
    "unsubscribed": false,
    "created": false,
    "updated": true,
    "companyLinked": false
  }
}
Creates a new contact in your CRM, or updates an existing one if a contact with the same email, linkedinUrl, or linkedinUrlSalesNav already exists (upsert). During updates, only non-empty fields are applied — null or empty values are ignored to preserve existing data.

Upsert matching

At least one identifier is required:
IdentifierDescription
emailPrimary email address — used as the main unique key
linkedinUrlLinkedIn profile URL — used as an alternative unique key
linkedinUrlSalesNavLinkedIn Sales Navigator profile URL — used as an alternative unique key
If a contact with the same email, linkedinUrl, or linkedinUrlSalesNav already exists, the endpoint updates it instead of creating a duplicate.

Linking to a company

You can link the contact to a company that already exists in your lemlist CRM using one of the following fields (in order of priority):
FieldDescription
companyIdDirect company ID — takes priority over the others
companyDomainCompany domain (e.g. lemlist.com) — used if companyId is not provided
companyLinkedinUrlCompany LinkedIn URL — used as a last resort
When a company is successfully linked, the response includes companyLinked: true and the companyId.

Owner assignment

You can assign an owner to the contact using the contactOwner field. Accepted formats:
FormatExample
User IDusr_2aB3cD4eF5gH6iJ7k
Team member emailjohn@yourcompany.com
If the provided value does not match a team member (invalid format, unknown email, or unknown user ID), the owner is silently ignored — no error or warning is returned. On creation, the contact defaults to the API key owner.

Authorizations

Authorization
string
header
required

Basic authentication header of the form Basic <encoded-value>, where <encoded-value> is the base64-encoded string username:password.

Body

application/json
email
string

Contact email address. Used as a unique key for upsert matching. At least one of email, linkedinUrl, or linkedinUrlSalesNav is required.

linkedinUrl
string

LinkedIn profile URL. Used as an alternative unique key for upsert matching. At least one of email, linkedinUrl, or linkedinUrlSalesNav is required.

linkedinUrlSalesNav
string

LinkedIn Sales Navigator profile URL. Used as an alternative unique key for upsert matching.

additionalEmails
string[]

Additional email addresses for the contact. Each must be a valid email address.

firstName
string

Contact first name.

lastName
string

Contact last name.

phone
string

Contact phone number.

jobTitle
string

Contact job title. If a company is linked, this is saved as part of the job data.

jobDescription
string

Contact job description. If a company is linked, this is saved as part of the job data.

picture
string

URL of the contact's profile picture.

timezone
string

Contact timezone.

industry
string

Contact industry.

languages
string

Contact languages.

location
string

Contact location.

skills
string

Contact skills.

summary
string

Contact summary or bio.

tagline
string

Contact tagline.

contactOwner
string

Owner of the contact. Can be a user ID (e.g. usr_...) or a team member's email address. If the provided value does not match a team member, the owner defaults to the API key owner.

source
string
default:api

Origin of the contact record. Set on creation only and cannot be updated afterwards. Defaults to api.

companyId
string

ID of a company already existing in lemlist to link to this contact. Takes priority over companyDomain and companyLinkedinUrl.

companyDomain
string

Domain of a company already existing in lemlist to link to this contact (e.g. lemlist.com). Used if companyId is not provided.

companyLinkedinUrl
string

LinkedIn URL of a company already existing in lemlist to link to this contact. Used if companyId and companyDomain are not provided.

{key}
any

Any additional key is treated as a custom field. Custom fields must be registered in the team's CRM field registry beforehand.

Response

Existing contact updated (upsert matched by email or LinkedIn URL)

success
boolean
data
object

Same shape as the 201 response, with created: false and updated: true.