lemlist Contacts API

CRM-side contacts, contact lists, list membership and exports.

Operations 8

GET /contacts/{idOrEmail} Get contact
DELETE /contacts/{idOrEmail} Delete Contact
GET /contacts Get contacts
POST /contacts Add and update contact
GET /contacts/lists Get Contact Lists
POST /contacts/lists Create Contact List
POST /contacts/lists/{listId}/entities Add or Remove Contacts in a List
GET /contacts/export Export Contact List

Work with this as data

Every API here is available over the APIs.io API and to AI agents over MCP.

MCP server

One button, every client — Claude, Cursor, VS Code and the rest.

https://apis.io/mcp

Tools for apis

7 MCP tools reach this
  • find_apisBrowse and filter every API in the catalog.
  • get_api_artifactsOne API's artifacts, grouped by type.
  • get_openapiThe primary OpenAPI for this API.
  • find_similar_apisAPIs that look like this one.
  • apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
  • resolveTurn a domain, URL or GitHub org into the provider it belongs to.
  • find_cohortsEvery scored population of providers in the catalog.
All 92 tools →

Call it yourself

curl for this page
This API
curl "https://apis.io/api/v1/apis/lemlist-contacts-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"

Discovery needs no key. Ratings and market analysis are Pro.

Get an API key

Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.

A second provider on the same verified email joins the account you already have.

OpenAPI Specification

lemlist-contacts-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  title: Lemlist Contacts API
  version: 1.0.0
  description: 'Operations tagged Contacts across 3 of this provider''s published API definitions: lemlist-openapi-v1-legacy.json, lemlist-openapi-v2.json, lemlist-openapi.yml. Each path carries the servers of the definition it was published in.'
servers:
- url: https://api.lemlist.com/api
tags:
- name: Contacts
paths:
  /contacts/{idOrEmail}:
    parameters:
    - name: idOrEmail
      in: path
      required: true
      example: '{{idOrEmail}}'
      schema:
        type: string
    get:
      summary: Get contact
      tags:
      - Contacts
      parameters:
      - name: Content
        in: header
        required: false
        example: application/json
        schema:
          type: string
      responses:
        '200':
          headers:
            Content-Type:
              schema:
                type: string
              example: application/json
          description: Success
          content:
            application/json:
              schema:
                type: object
                properties:
                  _id:
                    type: string
                  teamId:
                    type: string
                  email:
                    type: string
                    format: email
                  fullName:
                    type: string
                  fields:
                    type: object
                    properties:
                      firstName:
                        type: string
                      lastName:
                        type: string
                      company:
                        type: string
                  campaigns:
                    type: array
                    items:
                      type: object
                      properties:
                        campaignId:
                          type: string
                        campaignState:
                          type: string
                        leadState:
                          type: string
                  ownerId:
                    type: string
                  createdAt:
                    type: string
                    format: date-time
                  createdBy:
                    type: string
              example:
                _id: ctc_Ri5gMtaeDGufRQ3M2
                teamId: tea_8GdMrBZ3gf4p2rj2h
                email: chafik@lempire.co
                fullName: Chafik Gharbi
                fields:
                  firstName: Chafik
                  lastName: Gharbi
                  company: lempire
                campaigns:
                - campaignId: cam_C7BW5Z5ycSiRRWef6
                  campaignState: running
                  leadState: review
                ownerId: usr_h47tiJr87Zn7XtQHi
                createdAt: '2025-07-18T10:03:41.612Z'
                createdBy: usr_h47tiJr87Zn7XtQHi
    delete:
      summary: Delete Contact
      description: Deletes a lemlist contact resolved by its id (`ctc_xxx`) or email. Cascades to the contact's leads, opportunities, list associations, inbox conversations and activities. **No CRM-side propagation** — only the lemlist record is removed. Fails with `409 CONTACT_DELETE_BLOCKED` when the contact cannot be deleted right now — for example while an enrichment is still running (retry once it finishes); the response `error.message` states the specific reason.
      tags:
      - Contacts
      responses:
        '200':
          description: Contact deleted.
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                  deletedContactId:
                    type: string
                    description: ID of the deleted lemlist contact.
                required:
                - success
                - deletedContactId
              example:
                success: true
                deletedContactId: ctc_xW8Ou6C03Csv8vatp
        '401':
          description: The authentication you supplied is incorrect.
          content:
            text/plain:
              example: The authentication you supplied is incorrect
        '404':
          description: Contact not found (`CONTACT_NOT_FOUND`).
          content:
            application/json:
              example:
                success: false
                error:
                  code: CONTACT_NOT_FOUND
                  message: No contact found with the provided id or email
        '409':
          description: The contact cannot be deleted right now (`CONTACT_DELETE_BLOCKED`) — for example while an enrichment is in progress. The `error.message` states the specific reason; retry once it clears.
          content:
            application/json:
              example:
                success: false
                error:
                  code: CONTACT_DELETE_BLOCKED
                  message: Contact cannot be removed if an enrichment is in progress
        '405':
          description: Method not allowed.
    servers:
    - url: https://api.lemlist.com/api
  /contacts:
    parameters: []
    get:
      summary: Get contacts
      tags:
      - Contacts
      parameters:
      - name: Content
        in: header
        required: false
        example: application/json
        schema:
          type: string
      responses:
        '200':
          headers:
            Content-Type:
              schema:
                type: string
              example: application/json
          description: Success
          content:
            application/json:
              schema:
                type: array
                items:
                  type: object
                  properties:
                    _id:
                      type: string
                    teamId:
                      type: string
                    email:
                      type: string
                      format: email
                    fullName:
                      type: string
                    fields:
                      type: object
                      properties:
                        firstName:
                          type: string
                        lastName:
                          type: string
                        company:
                          type: string
                    campaigns:
                      type: array
                      items:
                        type: object
                        properties:
                          campaignId:
                            type: string
                          campaignState:
                            type: string
                          leadState:
                            type: string
                    ownerId:
                      type: string
                    createdAt:
                      type: string
                      format: date-time
                    createdBy:
                      type: string
              example:
              - _id: ctc_Ri5gMtaeDGufRQ3M2
                teamId: tea_8GdMrBZ3gf4p2rj2h
                email: chafik@lempire.co
                fullName: Chafik Gharbi
                fields:
                  firstName: Chafik
                  lastName: Gharbi
                  company: lempire
                campaigns:
                - campaignId: cam_C7BW5Z5ycSiRRWef6
                  campaignState: running
                  leadState: review
                ownerId: usr_h47tiJr87Zn7XtQHi
                createdAt: '2025-07-18T10:03:41.612Z'
                createdBy: usr_h47tiJr87Zn7XtQHi
              - _id: ctc_Lznm3LZ8DMR4WS3r8
                teamId: tea_8GdMrBZ3gf4p2rj2h
                email: chafik2@lempire.co
                fullName: Chafik Gharbi
                fields:
                  firstName: Chafik
                  lastName: Gharbi
                  company: lempire
                campaigns:
                - campaignId: cam_C7BW5Z5ycSiRRWef6
                  campaignState: running
                  leadState: review
                ownerId: usr_h47tiJr87Zn7XtQHi
                createdAt: '2025-07-18T10:03:41.612Z'
                createdBy: usr_h47tiJr87Zn7XtQHi
    post:
      summary: Add and update contact
      description: Creates a new contact or updates an existing one (upsert). If a contact with the same email, LinkedIn URL, or Sales Navigator URL already exists, it will be updated with the provided non-empty fields. Null or empty values are ignored during updates to preserve existing data. You can target an existing contact directly by providing `contactId`, bypassing email/LinkedIn matching. You can optionally link the contact to a company by providing `companyId`, `companyDomain`, or `companyLinkedinUrl`.
      tags:
      - Contacts
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                contactId:
                  type: string
                  description: Existing contact ID. Updates a specific contact by ID, bypassing email/LinkedIn matching. Can only be used to update an existing contact, not to create a new one. When provided, `email` and `linkedinUrl` are not required. At least one of `contactId`, `email`, `linkedinUrl`, or `linkedinUrlSalesNav` is required.
                email:
                  type: string
                  description: Contact email address. Used as a unique key for upsert matching. At least one of `contactId`, `email`, `linkedinUrl`, or `linkedinUrlSalesNav` is required.
                linkedinUrl:
                  type: string
                  description: LinkedIn profile URL. Used as an alternative unique key for upsert matching. At least one of `contactId`, `email`, `linkedinUrl`, or `linkedinUrlSalesNav` is required.
                linkedinUrlSalesNav:
                  type: string
                  description: LinkedIn Sales Navigator profile URL. Used as an alternative unique key for upsert matching.
                additionalEmails:
                  type: array
                  items:
                    type: string
                  description: Additional email addresses for the contact. Each must be a valid email address.
                firstName:
                  type: string
                  description: Contact first name.
                lastName:
                  type: string
                  description: Contact last name.
                phone:
                  type: string
                  description: Contact phone number.
                jobTitle:
                  type: string
                  description: Contact job title. If a company is linked, this is saved as part of the job data.
                jobDescription:
                  type: string
                  description: Contact job description. If a company is linked, this is saved as part of the job data.
                picture:
                  type: string
                  description: URL of the contact's profile picture.
                timezone:
                  type: string
                  description: Contact timezone.
                industry:
                  type: string
                  description: Contact industry.
                languages:
                  type: string
                  description: Contact languages.
                location:
                  type: string
                  description: Contact location.
                skills:
                  type: string
                  description: Contact skills.
                summary:
                  type: string
                  description: Contact summary or bio.
                tagline:
                  type: string
                  description: Contact tagline.
                contactOwner:
                  type: string
                  description: 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:
                  type: string
                  description: Origin of the contact record. Set on creation only and cannot be updated afterwards. Defaults to `api`.
                  default: api
                companyId:
                  type: string
                  description: ID of a company already existing in lemlist to link to this contact. Takes priority over `companyDomain` and `companyLinkedinUrl`.
                companyDomain:
                  type: string
                  description: Domain of a company already existing in lemlist to link to this contact (e.g. `lemlist.com`). Used if `companyId` is not provided.
                companyLinkedinUrl:
                  type: string
                  description: LinkedIn URL of a company already existing in lemlist to link to this contact. Used if `companyId` and `companyDomain` are not provided.
              additionalProperties:
                description: Any additional key is treated as a custom field. Custom fields must be registered in the team's CRM field registry beforehand.
            example:
              email: jane.smith@example.com
              firstName: Jane
              lastName: Smith
              linkedinUrl: https://linkedin.com/in/janesmith
              jobTitle: Product Manager
              companyDomain: acme.com
      responses:
        '201':
          description: Contact created successfully
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                  data:
                    type: object
                    properties:
                      _id:
                        type: string
                        description: Unique contact identifier
                      teamId:
                        type: string
                        description: Team ID
                      emails:
                        type: array
                        description: Contact email addresses
                        items:
                          type: object
                          properties:
                            value:
                              type: string
                      linkedinUrl:
                        type: string
                        description: LinkedIn profile URL
                      linkedinUrlSalesNav:
                        type: string
                        description: LinkedIn Sales Navigator URL
                      fields:
                        type: object
                        description: Key/value fields (firstName, lastName, phone, jobTitle, custom fields, etc.)
                        additionalProperties: true
                      ownerId:
                        type: string
                        description: Owner user ID
                      companyId:
                        type: string
                        description: Linked company ID (present only when a company was linked)
                      source:
                        type: string
                        description: Record origin
                      createdAt:
                        type: string
                        format: date-time
                        description: Creation timestamp
                      createdBy:
                        type: string
                        description: User ID who created the record
                      unsubscribed:
                        type: boolean
                        description: Whether the contact is unsubscribed
                      created:
                        type: boolean
                        description: '`true` when a new contact was created, `false` when an existing contact was updated.'
                      updated:
                        type: boolean
                        description: Present and set to `true` only when an existing contact was updated (i.e. `created` is `false`).
                      companyLinked:
                        type: boolean
                        description: Whether a company was successfully linked to the contact.
                  warnings:
                    type: array
                    description: Optional warnings (e.g. company resolution issues).
                    items:
                      type: object
                      properties:
                        code:
                          type: string
                        message:
                          type: string
              example:
                success: true
                data:
                  _id: ctc_xW8Ou6C03Csv8vatp
                  teamId: tea_8QvkOiBfPdb2ZRhHi
                  emails:
                  - value: jane.smith@example.com
                  linkedinUrl: https://www.linkedin.com/in/janesmith
                  fields:
                    firstName: Jane
                    lastName: Smith
                    jobTitle: Product Manager
                  ownerId: usr_ahfFktBBHUIxbVG5P
                  source: api
                  createdAt: '2025-10-28T00:40:37.917Z'
                  createdBy: usr_ahfFktBBHUIxbVG5P
                  unsubscribed: false
                  created: true
                  companyLinked: true
                  companyId: cpn_gG7PsmZFpEAnpMCHO
        '200':
          description: Existing contact updated (upsert matched by email or LinkedIn URL)
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                  data:
                    type: object
                    description: 'Same shape as the 201 response, with `created: false` and `updated: true`.'
              example:
                success: true
                data:
                  _id: ctc_xW8Ou6C03Csv8vatp
                  teamId: tea_8QvkOiBfPdb2ZRhHi
                  emails:
                  - value: jane.smith@example.com
                  fields:
                    firstName: Jane
                    lastName: Smith
                    jobTitle: Product Manager
                  ownerId: usr_ahfFktBBHUIxbVG5P
                  source: api
                  createdAt: '2025-10-28T00:40:37.917Z'
                  createdBy: usr_ahfFktBBHUIxbVG5P
                  unsubscribed: false
                  created: false
                  updated: true
                  companyLinked: false
        '400':
          description: Validation error
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                  error:
                    type: object
                    properties:
                      code:
                        type: string
                        description: 'Error code: `MISSING_IDENTIFIER`, `INVALID_CONTACT_ID`, `CONTACT_NOT_FOUND_BY_ID`, `INVALID_EMAIL`, `INVALID_ADDITIONAL_EMAILS`, `INVALID_LINKEDIN_URL`, `INVALID_FIELD`, or `CONTACT_VALIDATION_FAILED`.'
                      message:
                        type: string
              example:
                success: false
                error:
                  code: MISSING_IDENTIFIER
                  message: 'At least one identifier is required: email, linkedinUrl or contactId'
        '401':
          description: The authentication you supplied is incorrect
          content:
            text/plain:
              example: The authentication you supplied is incorrect
      parameters: []
    servers:
    - url: https://api.lemlist.com/api
  /contacts/lists:
    get:
      summary: Get Contact Lists
      description: Retrieves all static and dynamic contact lists for the team. Optionally filter by name.
      tags:
      - Contacts
      parameters:
      - name: search
        in: query
        required: false
        description: Filter lists by name (case-insensitive partial match).
        schema:
          type: string
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                type: array
                items:
                  type: object
                  properties:
                    _id:
                      type: string
                      description: Unique list ID (`clt_xxx` format)
                    name:
                      type: string
                      description: Name of the contact list
                    dynamic:
                      type: boolean
                      description: Whether the list is dynamic (auto-populated by filters) or static (manually managed)
              example:
              - _id: clt_abc123def456ghi78
                name: Nurturing
                dynamic: false
              - _id: clt_xyz789uvw012rst34
                name: Enterprise Prospects
                dynamic: true
        '400':
          description: Bad team
          content:
            text/plain:
              example: Bad team
        '401':
          description: The authentication you supplied is incorrect
          content:
            text/plain:
              example: The authentication you supplied is incorrect
        '405':
          description: Method not allowed
      security:
      - basicAuth: []
    post:
      summary: Create Contact List
      description: Creates a new static contact list. After creating the list, use `POST /contacts/lists/{listId}/entities` to add contacts to it.
      tags:
      - Contacts
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
              - name
              properties:
                name:
                  type: string
                  maxLength: 200
                  description: Name of the contact list to create (max 200 characters).
            example:
              name: Nurturing
      responses:
        '201':
          description: Contact list created successfully
          content:
            application/json:
              schema:
                type: object
                properties:
                  message:
                    type: string
                  list:
                    type: object
                    properties:
                      id:
                        type: string
                        description: Unique list ID (`clt_xxx` format)
                      name:
                        type: string
                        description: Name of the created list
              example:
                message: Contact list created successfully
                list:
                  id: clt_abc123def456ghi78
                  name: Nurturing
        '400':
          description: 'Possible errors: Bad team / name is required / name too long'
          content:
            text/plain:
              example: name is required and must be a non-empty string
        '401':
          description: The authentication you supplied is incorrect
          content:
            text/plain:
              example: The authentication you supplied is incorrect
        '405':
          description: Method not allowed
      security:
      - basicAuth: []
    servers:
    - url: https://api.lemlist.com/api
  /contacts/lists/{listId}/entities:
    parameters:
    - name: listId
      in: path
      required: true
      description: The unique identifier of the contact list (`clt_xxx` format). Must be a **static** contact list.
      example: clt_xxxxxxxxxxxxxxxxx
      schema:
        type: string
        pattern: ^clt_[a-zA-Z0-9]+$
    post:
      summary: Add or Remove Contacts in a List
      description: 'Adds existing CRM contacts to a static contact list, or removes them when `?action=remove` is set.


        - **Add** (default): send a `POST` with a `contactIds` body. Contacts already in the list are silently skipped (no duplicates) and reported in `alreadyInList`.

        - **Remove**: send a `POST` with `?action=remove` and a `contactIds` body. Contacts that are not in the list are silently skipped; `removedCount` reflects the associations actually removed. This only affects list membership, the contacts are not deleted from your CRM.


        The list must be a **static** contact list (`clt_xxx`). Dynamic lists (auto-populated by filter rules) and company lists are rejected.


        **Removal uses `POST ?action=remove` on purpose:** a `DELETE` request body is dropped by our stack, so `DELETE` on this path is **not supported** and returns `405 Method Not Allowed`.'
      tags:
      - Contacts
      parameters:
      - name: action
        in: query
        required: false
        description: Omit to **add** the contacts to the list. Set to `remove` to **remove** them from the list.
        example: remove
        schema:
          type: string
          enum:
          - remove
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
              - contactIds
              properties:
                contactIds:
                  type: array
                  items:
                    type: string
                    pattern: ^ctc_[a-zA-Z0-9]+$
                  minItems: 1
                  maxItems: 1000
                  description: Array of contact IDs (`ctc_xxx` format) to add to or remove from the list. Required, non-empty, maximum 1,000 per request.
            example:
              contactIds:
              - ctc_xxxxxxxxxxxxxxxxx
              - ctc_yyyyyyyyyyyyyyyyy
      responses:
        '200':
          description: Contacts added to or removed from the list successfully. The response body depends on `action`.
          content:
            application/json:
              schema:
                type: object
                properties:
                  message:
                    type: string
                  addedCount:
                    type: integer
                    description: Number of contacts added to the list (add only).
                  alreadyInList:
                    type: integer
                    description: Number of contacts that were already in the list and therefore skipped (add only).
                  removedCount:
                    type: integer
                    description: Number of list associations actually removed (remove only). Contacts that were not in the list are not counted.
              examples:
                add:
                  summary: Add contacts (no action)
                  value:
                    message: Contacts added to list successfully
                    addedCount: 2
                    alreadyInList: 0
                remove:
                  summary: Remove contacts (action=remove)
                  value:
                    message: Contacts removed from list successfully
                    removedCount: 2
        '400':
          description: 'Possible errors: Bad team / Invalid listId format (expected clt_xxx) / contactIds is required and must be a non-empty array / Maximum 1,000 contacts per request / All contactIds must be in ctc_xxx format / List is not a contact list / Cannot manually add contacts to a dynamic list / Cannot manually remove contacts from a dynamic list.'
          content:
            text/plain:
              example: contactIds is required and must be a non-empty array
        '401':
          description: The authentication you supplied is incorrect
          content:
            text/plain:
              example: The authentication you supplied is incorrect
        '404':
          description: Contact list not found
          content:
            text/plain:
              example: Contact list not found
        '405':
          description: Method not allowed. `DELETE` on this path is not supported because the request body is dropped by our stack. Use `POST ?action=remove` to remove contacts.
          content:
            text/plain:
              example: Method not allowed
        '500':
          description: Internal error while updating the list
          content:
            text/plain:
              example: Failed to add contacts to list
      security:
      - basicAuth: []
    servers:
    - url: https://api.lemlist.com/api
  /contacts/export:
    get:
      summary: Export Contact List
      description: 'Exports contacts or companies from a CRM list as a CSV file. The response is streamed as `text/csv` with a `Content-Disposition: attachment` header.


        The exported columns depend on the `entity` type:

        - **contact**: firstName, lastName, email, linkedinUrl, companyName, jobTitle, phone, status, owner, campaigns, contactLists, and more.

        - **company**: name, domain, linkedinUrl, industry, website, status, size, owner, numberOfContacts, companyLists, and more.


        Custom fields are included as additional columns.'
      tags:
      - Contacts
      parameters:
      - name: listId
        in: query
        required: true
        description: The contact list ID to export (`clt_xxx` format), or `"all"` to export all contacts.
        example: clt_abc123def456ghi78
        schema:
          type: string
      - name: entity
        in: query
        required: false
        description: The type of entities to export. Defaults to `"contact"`.
        schema:
          type: string
          enum:
          - contact
          - company
          default: contact
      responses:
        '200':
          description: CSV file download
          content:
            text/csv:
              example: 'firstName,lastName,email,companyName,jobTitle,status

                John,Doe,john@example.com,Acme Inc,CEO,interested'
        '400':
          description: Bad team
          content:
            text/plain:
              example: Bad team
        '401':
          description: Unauthorized
      security:
      - basicAuth: []
    servers:
    - url: https://api.lemlist.com/api
components:
  schemas:
    FieldRejection:
      type: object
      description: A value lemlist refused to write on a Contact or Company, with the reason why. Surfaced under `fieldRejections[]` on those objects; filter a list endpoint to only flagged records via the `fieldRejectionReason` query param.
      properties:
        field:
          type: string
          description: The record field the rejected value targeted (e.g. `emails`, `linkedinUrl`, `domain`).
        reason:
          type: string
          description: Why the value was rejected, prefixed by its origin — `enrichment_*` (raised while enriching) or `crm_sync_*` (raised during CRM sync). Same values accepted by the `fieldRejectionReason` query param.
        source:
          type: string
          description: Where the rejection came from — an enrichment source (`lemrich`) or a CRM provider (`hubspot`, `salesforce`, `pipedrive`).
        conflictingRecordId:
          type: string
          description: For duplicate reasons, the id of the record that already holds the value — use it to merge or remap before resolving the duplicate. Omitted for non-duplicate reasons.
        rejectedValue:
          type: string
          description: The value that was refused.
        rejectedAt:
          type: string
          format: date-time
          description: When the rejection was recorded.
    Contact:
      type: object
      description: A contact record in your CRM. Not to be confused with a lead which is a contact specifically added to a campaign.
      properties:
        _id:
          type: string
          description: Unique contact identifier
        teamId:
          type: string
          description: Team identifier the contact belongs to
        fullName:
          type: string
          description: Contact's calculated full name
        email:
          type: string
          format: email
          description: Contact's primary email address
        fields:
          type: object
          description: Custom fields associated with the contact
          additionalProperties: true
        campaigns:
          type: array
          description: List of campaigns the contact is associated with
          items:
            type: object
            properties:
              campaignId:
      

# --- truncated at 32 KB (33 KB total) ---
# Full source: https://raw.githubusercontent.com/api-evangelist/lemlist/refs/heads/main/openapi/lemlist-contacts-api-openapi.yml