All integrations

lemlist

BUSINESS · CRM & SUPPORT

Campaigns, leads, and the unified inbox under that person’s own access.

Acts as the person, not as itself

Each user connects their own account. Every call carries both identities — the agent and the person it is acting for — so the agent can never reach past what that individual can already do.

Credentials never touch the agent

Tokens live in the vault and attach server-side at call time. The agent holds a session, not a secret, and revoking access does not mean rotating a key.

Every call on the record

Who asked, which agent acted, which action ran, and the verdict that let it through — one audit trail across every integration, not one per vendor.

What an agent can do

Each action is granted on its own. An agent allowed to read is not thereby allowed to write, and the scope beside each row is what the acting user must have connected for it to run at all.

lemlist_delete_activities_by_activityid_recording_transcriptWRITE

Delete Activity Recording & Transcript via DELETE /activities/{activityId}/recording-transcript

api
lemlist_delete_campaigns_by_campaignid_leads_by_emailWRITE

Unsubscribe Lead from Campaign via DELETE /campaigns/{campaignId}/leads/{email}

api
lemlist_delete_campaigns_by_campaignid_leads_by_leadidWRITE

Delete or Unsubscribe Lead via DELETE /campaigns/{campaignId}/leads/{leadId}

api
lemlist_delete_companies_by_companyidWRITE

Deletes a lemlist company. Refuses by default when contacts are still attached — pass `force=true` to detach them (the `companyId` field is unset on each contact) before deleting the company. **No CRM-side propagation:** only the lemlist record is removed. Designed for the contact-to-company remapping workflow: after reassigning the contacts of a duplicate company to the canonical one (via `POST /contacts/{idOrEmail}`), call this endpoint to drop the now-empty duplicate. via DELETE /companies/{companyId}

api
lemlist_delete_contacts_by_idoremailWRITE

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. via DELETE /contacts/{idOrEmail}

api
lemlist_delete_database_personas_by_personaidWRITE

Permanently deletes one of your team's personas. There is no undo. An unknown id, a persona belonging to another team, and the persona lemlist auto-generates from your AI business context all answer the same `404`: they are indistinguishable by design. This endpoint is in closed beta and answers `403` unless the beta is enabled for your team. via DELETE /database/personas/{personaId}

api
lemlist_delete_deliverability_alerts_by_alertidWRITE

Delete Deliverability Alert via DELETE /deliverability/alerts/{alertId}

api
lemlist_delete_hooks_by_hookidWRITE

Delete Webhook via DELETE /hooks/{hookId}

api
lemlist_delete_inbox_by_contactid_drafts_by_draftidWRITE

Soft-deletes a draft by setting its deletedAt timestamp. via DELETE /inbox/{contactId}/drafts/{draftId}

api
lemlist_delete_inbox_conversations_labels_by_contactidWRITE

Removes one or more labels from one conversation. via DELETE /inbox/conversations/labels/{contactId}

api
lemlist_delete_leads_by_leadid_variablesWRITE

Erases the values of custom variables on a lead. via DELETE /leads/{leadId}/variables

api
lemlist_delete_schedules_by_scheduleidWRITE

Delete Schedule via DELETE /schedules/{scheduleId}

api
lemlist_delete_sequences_by_sequenceid_steps_by_stepidWRITE

Delete Sequence Step via DELETE /sequences/{sequenceId}/steps/{stepId}

api
lemlist_delete_sequences_by_sequenceid_steps_by_stepid_ab_testWRITE

Deletes a variant of the A/B test and ends the test. Deleting `B` (default) drops variant B; deleting `A` promotes variant B to A. Requires the Email Pro plan. via DELETE /sequences/{sequenceId}/steps/{stepId}/ab-test

api
lemlist_delete_sequences_by_sequenceid_steps_by_stepid_branches_by_branchsequenceidWRITE

Removes a branch and the whole sub-tree behind it - the branch's own sub-sequence, and every sequence only reachable through it. `removedSequenceIds` lists what was deleted alongside the branch entry; a sequence another step still points at is left alone. A step keeps at least one branch besides Else, and the Else branch itself is never removable. Removal is refused once leads have entered the campaign, and again while any lead sits anywhere inside the sub-tree. via DELETE /sequences/{sequenceId}/steps/{stepId}/branches/{branchSequenceId}

api
lemlist_delete_unsubscribes_by_emailWRITE

(deprecated) Delete Unsubscribe Email via DELETE /unsubscribes/{email}

api
lemlist_delete_user_email_accounts_by_emailaccountidWRITE

Disconnect Email Account via DELETE /user/email-accounts/{emailAccountId}

api
lemlist_delete_v2_unsubscribes_contacts_by_contactidWRITE

Removes the unsubscribed (do-not-contact) flag from a contact. via DELETE /v2/unsubscribes/contacts/{contactId}

api
lemlist_delete_v2_unsubscribes_variables_by_valueWRITE

Removes a variable from the unsubscribe list. Variables with a protected source (LEAD or ABUSE) cannot be re-subscribed. via DELETE /v2/unsubscribes/variables/{value}

api
lemlist_delete_watchlistWRITE

Delete Signal Agent via DELETE /watchlist

api
lemlist_get_activitiesREAD

Get Many Activities via GET /activities

api
lemlist_get_campaignsREAD

Get Many Campaigns via GET /campaigns

api
lemlist_get_campaigns_by_campaignidREAD

Get Campaign via GET /campaigns/{campaignId}

api
lemlist_get_campaigns_by_campaignid_export_by_exportid_statusREAD

Check the status of an asynchronous campaign export. via GET /campaigns/{campaignId}/export/{exportId}/status

api
lemlist_get_campaigns_by_campaignid_export_leadsREAD

(deprecated) Export leads from a campaign with filtering options. Returns leads in CSV or JSON format based on their state (e.g., contacted, interested, replied, etc.). via GET /campaigns/{campaignId}/export/leads

api
lemlist_get_campaigns_by_campaignid_export_startREAD

Start an asynchronous export of all campaign statistics. The final export result is a CSV file. via GET /campaigns/{campaignId}/export/start

api
lemlist_get_campaigns_by_campaignid_leadsREAD

Get Campaign Leads via GET /campaigns/{campaignId}/leads

api
lemlist_get_campaigns_by_campaignid_schedulesREAD

Get Campaign Schedules via GET /campaigns/{campaignId}/schedules

api
lemlist_get_campaigns_by_campaignid_sequencesREAD

Get Campaign Sequences via GET /campaigns/{campaignId}/sequences

api
lemlist_get_campaigns_by_campaignid_statutesREAD

Retrieves validation statutes for a campaign, including errors that block launching and warnings about daily limits, DNS issues, etc. Uses the same validation engine as the lemlist UI. via GET /campaigns/{campaignId}/statutes

api
lemlist_get_campaigns_reportsREAD

Retrieve reports for one or multiple campaigns. Returns aggregated statistics and export status for the specified campaigns. via GET /campaigns/reports

api
lemlist_get_companiesREAD

Get Many Companies via GET /companies

api
lemlist_get_companies_by_companyid_notesREAD

Get Company Notes via GET /companies/{companyId}/notes

api
lemlist_get_contact_sourcingREAD

Reads one contact-sourcing run — by its own id, or the latest run of an account. The HTTP status carries the run state: `200` the run completed and `contacts` is filled, `202` the run is still queued or going (poll again), `400` the run failed and `error` says why, `404` no such run. Exactly one of `runId` or `companyId` is required. via GET /contact-sourcing

api
lemlist_get_contactsREAD

Retrieves contacts by IDs/emails, or searches/lists contacts by name, email, contact list, campaign membership, or company link. When using `idsOrEmails`, returns an array of matching contacts directly. When using `search`, `email`, `listId`, `notInAnyCampaign`, any of the `company*` filters, or no filter at all, returns a paginated response with `data`, `total`, `limit`, and `offset` fields. You can combine filters together to narrow results (e.g. `listId` with `search`, or `notInAnyCampaign` with `companyId`). Calling the endpoint without any filter returns all contacts of the team, paginated. The `company*` filters (`companyId`, `companyDomain`, `companyLinkedinUrl`, `companySalesnavUrl`) are mutually exclusive — use only one at a time. `companyDomain` / `companyLinkedinUrl` / `companySalesnavUrl` are resolved to a `companyId` through the Companies collection; if no matching company exists, the endpoint returns an empty list with `total: 0` (not an error), which keeps automation flows simple. via GET /contacts

api
lemlist_get_contacts_by_idoremailREAD

Get Contact via GET /contacts/{idOrEmail}

api
lemlist_get_contacts_exportREAD

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. via GET /contacts/export

api
lemlist_get_contacts_listsREAD

Retrieves all static and dynamic contact lists for the team. Optionally filter by name. via GET /contacts/lists

api
lemlist_get_crm_filtersREAD

Get CRM Filters via GET /crm/filters

api
lemlist_get_database_filtersREAD

Get Database Filters via GET /database/filters

api
lemlist_get_database_personasREAD

Lists the personas saved by your team. A persona is a named, reusable set of People Database filters; its id can then be referenced elsewhere in the API, for example through the `persona` filter of a Signal Agent. Personas are team-shared: every member sees the same list. Results are sorted by creation date, most recent first, and capped at 200. The auto-generated persona lemlist derives from your AI business context is never returned; only the personas your team created are. This endpoint is in closed beta and answers `403` unless the beta is enabled for your team. via GET /database/personas

api
lemlist_get_deliverability_alertsREAD

List Deliverability Alerts via GET /deliverability/alerts

api
lemlist_get_deliverability_alerts_by_alertidREAD

Get Deliverability Alert via GET /deliverability/alerts/{alertId}

api
lemlist_get_enrich_by_enrichidREAD

Get Enrichment Result via GET /enrich/{enrichId}

api
lemlist_get_fieldsREAD

List Fields via GET /fields

api
lemlist_get_hooksREAD

Get Many Webhooks via GET /hooks

api
lemlist_get_inboxREAD

Get Many Inboxes via GET /inbox

api
lemlist_get_inbox_by_contactidREAD

Get Contact Messages via GET /inbox/{contactId}

api
lemlist_get_inbox_by_contactid_draftsREAD

Lists all non-deleted drafts for a specific contact. via GET /inbox/{contactId}/drafts

api
lemlist_get_inbox_by_contactid_drafts_by_draftidREAD

Retrieves a single draft with its full content, including attachments. via GET /inbox/{contactId}/drafts/{draftId}

api
lemlist_get_inbox_labelsREAD

List all labels available to your team. via GET /inbox/labels

api
lemlist_get_inbox_labels_by_labelidREAD

Get info of a specific label. via GET /inbox/labels/{labelId}

api
lemlist_get_leadsREAD

Retrieve a lead using either their email address or lead ID via GET /leads

api
lemlist_get_leads_by_emailREAD

Get Lead by Email via GET /leads/{email}

api
lemlist_get_lemwarm_by_usermailboxid_settingsREAD

Get lemwarm Settings via GET /lemwarm/{userMailboxId}/settings

api
lemlist_get_schedulesREAD

Get Many Schedules via GET /schedules

api
lemlist_get_schedules_by_scheduleidREAD

Get Schedule via GET /schedules/{scheduleId}

api
lemlist_get_sequences_by_sequenceid_steps_by_stepid_ab_testREAD

Returns variant B (subject, message, config) of the A/B test on a step. Requires the Email Pro plan. via GET /sequences/{sequenceId}/steps/{stepId}/ab-test

api
lemlist_get_sequences_by_sequenceid_steps_by_stepid_branchesREAD

Every branch of a condition step, in execution order, with the Else branch last. A condition step holds an ordered list of branches, each owning the sub-sequence the leads it matches walk into. Array order is execution priority: the first branch whose test matches takes the lead, and the Else branch at the end catches everyone no branch matched. A branch is addressed by its `sequenceId`, never by position - a reorder moves positions, the sub-sequence id is what the runtime routes leads to. Reading branches is not gated; only the writes are in closed beta. via GET /sequences/{sequenceId}/steps/{stepId}/branches

api
lemlist_get_tasksREAD

Retrieve tasks with optional filtering and pagination. Tasks marked as `done` are excluded from results. via GET /tasks

api
lemlist_get_teamREAD

Get Team via GET /team

api
lemlist_get_team_creditsREAD

Get Team Credits via GET /team/credits

api
lemlist_get_team_crmusersREAD

Get Team CRM Users via GET /team/crmUsers

api
lemlist_get_team_sendersREAD

Get Team Senders via GET /team/senders

api
lemlist_get_unsubs_exportREAD

(deprecated) Export Unsubscribes via GET /unsubs/export

api
lemlist_get_unsubscribesREAD

(deprecated) Get Many Unsubscribes via GET /unsubscribes

api
lemlist_get_unsubscribes_by_emailREAD

(deprecated) Get Unsubscribe by Email via GET /unsubscribes/{email}

api
lemlist_get_user_channelsREAD

Get User Channels via GET /user/channels

api
lemlist_get_users_by_useridREAD

Get User via GET /users/{userId}

api
lemlist_get_v2_campaigns_by_campaignid_export_leadsREAD

Export leads from a campaign with filtering options. Returns leads in CSV or JSON format based on their state (e.g., contacted, interested, replied, etc.). via GET /v2/campaigns/{campaignId}/export/leads

api
lemlist_get_v2_campaigns_by_campaignid_statsREAD

Retrieve detailed statistics for a specific campaign, with filtering options by date, user, A/B testing, and communication channels. via GET /v2/campaigns/{campaignId}/stats

api
lemlist_get_v2_unsubscribes_contacts_by_contactidREAD

Checks whether a contact is unsubscribed (do-not-contact). via GET /v2/unsubscribes/contacts/{contactId}

api
lemlist_get_v2_unsubscribes_exports_contactsREAD

Exports all contacts with their subscription status to a CSV file. via GET /v2/unsubscribes/exports/contacts

api
lemlist_get_v2_unsubscribes_exports_variablesREAD

Exports all unsubscribed variables to a CSV file. via GET /v2/unsubscribes/exports/variables

api
lemlist_get_v2_unsubscribes_variablesREAD

Retrieves a paginated list of all unsubscribed variables (emails, domains, LinkedIn URLs, phone numbers). via GET /v2/unsubscribes/variables

api
lemlist_get_v2_unsubscribes_variables_by_valueREAD

Retrieves a specific unsubscribed variable by its value. via GET /v2/unsubscribes/variables/{value}

api
lemlist_get_watchlistREAD

List Signal Agents via GET /watchlist

api
lemlist_get_watchlist_filter_valuesREAD

Autocomplete filter values via GET /watchlist/filter-values

api
lemlist_get_watchlist_filtersREAD

List allowed filters per signal type via GET /watchlist/filters

api
lemlist_get_watchlist_historyREAD

Get Signal Agent configuration history via GET /watchlist/history

api
lemlist_get_watchlist_libraryREAD

List available signal types via GET /watchlist/library

api
lemlist_get_watchlist_signalsREAD

Get Signal Agent signals via GET /watchlist/signals

api
lemlist_patch_campaigns_by_campaignidWRITE

Update Campaign via PATCH /campaigns/{campaignId}

api
lemlist_patch_campaigns_by_campaignid_leads_by_leadidWRITE

Update Lead in a Campaign via PATCH /campaigns/{campaignId}/leads/{leadId}

api
lemlist_patch_deliverability_alerts_by_alertidWRITE

Update Deliverability Alert via PATCH /deliverability/alerts/{alertId}

api
lemlist_patch_inbox_by_contactid_drafts_by_draftidWRITE

Partially updates an existing draft. Only the provided fields will be updated. via PATCH /inbox/{contactId}/drafts/{draftId}

api
lemlist_patch_leads_by_leadid_variablesWRITE

Update values of custom variables for a lead. via PATCH /leads/{leadId}/variables

api
lemlist_patch_lemwarm_by_usermailboxid_settingsWRITE

Update lemwarm Settings via PATCH /lemwarm/{userMailboxId}/settings

api
lemlist_patch_schedules_by_scheduleidWRITE

Update Schedule via PATCH /schedules/{scheduleId}

api
lemlist_patch_sequences_by_sequenceid_steps_by_stepidWRITE

Update Sequence Step via PATCH /sequences/{sequenceId}/steps/{stepId}

api
lemlist_patch_sequences_by_sequenceid_steps_by_stepid_ab_testWRITE

Edits variant B content/config of the A/B test on a step. Only the provided fields are updated; unknown fields are rejected. Allowed while the campaign is running. Requires the Email Pro plan. via PATCH /sequences/{sequenceId}/steps/{stepId}/ab-test

api
lemlist_patch_sequences_by_sequenceid_steps_by_stepid_branchesWRITE

Rewrites the execution priority of a condition step's branches. Order is priority: the first branch whose test matches takes the lead. `order` must list every non-fallback branch of the step exactly once. The Else branch is not orderable and always stays last, so it is left out of the list. Sending the order the step already has is a no-op that still returns the branches. via PATCH /sequences/{sequenceId}/steps/{stepId}/branches

api
lemlist_patch_sequences_by_sequenceid_steps_by_stepid_branches_by_branchsequenceidWRITE

Renames a branch and/or changes what it tests. Send only the halves you want to change. The two halves are gated differently once leads have entered the campaign: a rename still goes through, while re-selecting what the branch tests is refused with `409`. A body that does both on a running campaign is refused whole - the request is atomic, so the rename does not land either. Send the rename on its own if that is what you need. `conditionKey` is refused: every branch of a step shares the step's condition. The Else branch is neither renamable nor editable. via PATCH /sequences/{sequenceId}/steps/{stepId}/branches/{branchSequenceId}

api
lemlist_patch_tasksWRITE

Update task details such as assignment, due date, title, message, priority, or completion status. via PATCH /tasks

api
lemlist_patch_watchlistWRITE

Update Signal Agent via PATCH /watchlist

api
lemlist_post_campaignsWRITE

Create Campaign via POST /campaigns

api
lemlist_post_campaigns_by_campaignid_duplicateWRITE

Duplicate Campaign via POST /campaigns/{campaignId}/duplicate

api
lemlist_post_campaigns_by_campaignid_leadsWRITE

Create Lead in Campaign via POST /campaigns/{campaignId}/leads

api
lemlist_post_campaigns_by_campaignid_leads_by_leadidoremail_interestedWRITE

Mark Lead as Interested in Campaign via POST /campaigns/{campaignId}/leads/{leadIdOrEmail}/interested

api
lemlist_post_campaigns_by_campaignid_leads_by_leadidoremail_notinterestedWRITE

Mark Lead as Not Interested in Campaign via POST /campaigns/{campaignId}/leads/{leadIdOrEmail}/notinterested

api
lemlist_post_campaigns_by_campaignid_leads_by_leadidoremail_steps_by_stepid_skipWRITE

Skip one step of a running campaign for a single lead. Cannot be undone. via POST /campaigns/{campaignId}/leads/{leadIdOrEmail}/steps/{stepId}/skip

api
lemlist_post_campaigns_by_campaignid_leads_importWRITE

Import Leads from CRM via POST /campaigns/{campaignId}/leads/import

api
lemlist_post_campaigns_by_campaignid_pauseWRITE

Pause Campaign via POST /campaigns/{campaignId}/pause

api
lemlist_post_campaigns_by_campaignid_schedules_by_scheduleidWRITE

Associate Schedule with Campaign via POST /campaigns/{campaignId}/schedules/{scheduleId}

api
lemlist_post_campaigns_by_campaignid_startWRITE

Start Campaign via POST /campaigns/{campaignId}/start

api
lemlist_post_campaigns_by_campaignid_steps_by_stepid_skipWRITE

Skip one step of a running campaign for every lead. Cannot be undone. via POST /campaigns/{campaignId}/steps/{stepId}/skip

api
lemlist_post_companiesWRITE

Creates a new company or updates an existing one (upsert). If a company with the same domain, 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 company directly by providing `companyId`, bypassing domain/LinkedIn matching — in that case `name` and `domain` become optional. via POST /companies

api
lemlist_post_companies_by_companyid_notesWRITE

Create Company Note via POST /companies/{companyId}/notes

api
lemlist_post_companies_mergeWRITE

Merges up to 10 lemlist companies into one. The survivor (`primaryId`) keeps its id and every value it holds; its empty fields are filled from the other companies, which are then deleted. Everything attached to a deleted company (contacts, activities, tasks, list memberships) is moved to the survivor. When a CRM is connected, the survivor keeps its CRM link (or adopts the first linked record's when it has none) and receives the merged values there; lemlist never merges or deletes anything in the CRM itself, so the other records' CRM entries stay in the CRM, unlinked from lemlist — merge them CRM-side too, or a CRM import may recreate the duplicate. The companies are folded into the survivor one at a time and the run **stops at the first failure**: `mergedIds` lists what went through, `remainingIds` what still exists. A first-fold failure returns an error instead — nothing was written. **No undo:** deleted companies are gone. via POST /companies/merge

api
lemlist_post_contact_sourcingWRITE

Starts an AI contact-sourcing run for one or more accounts: sources each company's employees from the People Database and classifies them into a buying committee (decision maker / user / influencer) with an ICP fit score. One account or two hundred, same call — pass a list of one. Runs are asynchronous: the response carries a `runId` per account. Poll `GET /contact-sourcing` or subscribe to the `contactSourcingDone` webhook for the result. The call answers `200` even when some accounts could not be started — one unrunnable account among 200 is not a reason to fail the rest. Read both `results` and `errors`. By default an account that already has a committee is not re-run: its previous run comes back with `status: "reused"` and nothing is charged. `overwrite: true` forces a fresh run, but never stacks a second one on a run still going — that one is returned as `reused` instead, so retrying a timed-out request cannot charge you twice. Takes lemlist company ids only. To start from a domain or LinkedIn URL, resolve it first with `GET /companies?idsOrDomains=`. via POST /contact-sourcing

api
lemlist_post_contact_sourcing_contactsWRITE

Turns one contact-sourcing recommendation into a lemlist contact. `leadId` comes from a run's `contacts[].leadId` — a People-Database id, not a contact id. `companyId` is required and verified: if the person's profile now puts them at a different company, the contact is not filed under the account asked for and the call answers 409. via POST /contact-sourcing/contacts

api
lemlist_post_contactsWRITE

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`. via POST /contacts

api
lemlist_post_contacts_listsWRITE

Creates a new static contact list. After creating the list, use `POST /contacts/lists/{listId}/entities` to add contacts to it. via POST /contacts/lists

api
lemlist_post_contacts_lists_by_listid_entitiesWRITE

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`. via POST /contacts/lists/{listId}/entities

api
lemlist_post_contacts_mergeWRITE

Merges up to 10 lemlist contacts into one. The survivor (`primaryId`) keeps its id and every value it holds; its empty fields are filled from the other contacts, which are then deleted. Everything attached to a deleted contact (leads in campaigns, activities, tasks, list memberships, inbox conversations) is moved to the survivor. When a CRM is connected, the survivor keeps its CRM link (or adopts the first linked record's when it has none) and receives the merged values there; lemlist never merges or deletes anything in the CRM itself, so the other records' CRM entries stay in the CRM, unlinked from lemlist — merge them CRM-side too, or a CRM import may recreate the duplicate. The contacts are folded into the survivor one at a time and the run **stops at the first failure**: `mergedIds` lists what went through, `remainingIds` what still exists. A first-fold failure returns an error instead — nothing was written. **Email addresses:** the survivor keeps its own; a loser's addresses are dropped, unless the survivor has none (then it takes the first loser's). **No undo:** deleted contacts are gone. via POST /contacts/merge

api
lemlist_post_database_companiesWRITE

Search the lemlist Companies database using structured filters with pagination support. Returns comprehensive company data including technologies used, location, employee count, and other business intelligence. via POST /database/companies

api
lemlist_post_database_peopleWRITE

This endpoint allows you to query our People database. To do so, you may use the following parameters: filters (required), page (optional), size (optional), and excludes (optional). Each filter should have the following properties: filterId (filter identifier), in (list of the values you want to include), and out (list of the values you want to exclude). To know which filters you are able to use, refer to the GET Filters section. The `department` filter accepts the following values: `Sales`, `Customer service`, `Engineering`, `Marketing`, `Operations`, `Human Resources`, `Finance / Legal / Admin`, `Other`. via POST /database/people

api
lemlist_post_database_personasWRITE

Creates a persona for your team from a name and a set of People Database filters. Use [Get Database Filters](/api-reference/endpoints/people-database/get-database-filters) to discover the valid `filterId` values. Filters carry no `type` property: it is derived from `filterId` server-side. Filters that require a plan your team does not have are dropped silently, so the persona is stored with the subset your plan allows. Only the created id is returned. The stored `name` and `filters` are sanitized and plan-gated server-side, so echoing the request payload back would misreport what was persisted; call [List Personas](/api-reference/endpoints/people-database/list-personas) to read the stored persona. This endpoint is in closed beta and answers `403` unless the beta is enabled for your team. via POST /database/personas

api
lemlist_post_deliverability_alertsWRITE

Create Deliverability Alert via POST /deliverability/alerts

api
lemlist_post_enrichWRITE

Enrich Data via POST /enrich

api
lemlist_post_hooksWRITE

Add Webhook via POST /hooks

api
lemlist_post_inbox_by_contactid_draftsWRITE

Creates a new draft for a specific contact. The source is automatically set to "api". via POST /inbox/{contactId}/drafts

api
lemlist_post_inbox_conversations_labels_by_contactidWRITE

Attaches one or more labels to one or more conversations. via POST /inbox/conversations/labels/{contactId}

api
lemlist_post_inbox_emailWRITE

Send Email via POST /inbox/email

api
lemlist_post_inbox_labelsWRITE

Creates a new label available to the team. via POST /inbox/labels

api
lemlist_post_inbox_linkedinWRITE

Send LinkedIn Message via POST /inbox/linkedin

api
lemlist_post_inbox_smsWRITE

Sends an SMS to a contact through the lemlist inbox. The message is sent to the contact's phone number (`phone` field, or the first entry of `phones`). Sending consumes SMS credits, one per message segment. via POST /inbox/sms

api
lemlist_post_inbox_whatsappWRITE

Send WhatsApp Message via POST /inbox/whatsapp

api
lemlist_post_leads_by_leadid_enrichWRITE

Enrich Lead via POST /leads/{leadId}/enrich

api
lemlist_post_leads_by_leadid_variablesWRITE

Add custom variables to a lead and sets values for that specific lead. via POST /leads/{leadId}/variables

api
lemlist_post_leads_interested_by_leadidoremailWRITE

Mark a lead as interested across all campaigns via POST /leads/interested/{leadIdOrEmail}

api
lemlist_post_leads_notinterested_by_leadidoremailWRITE

Mark a lead as not interested across all campaigns via POST /leads/notinterested/{leadIdOrEmail}

api
lemlist_post_leads_pause_by_leadidWRITE

Pause Lead via POST /leads/pause/{leadId}

api
lemlist_post_leads_review_by_leadidWRITE

Use this endpoint to launch a lead that is waiting for review, without having to enable campaign-wide auto-review. You're auto launching this specific lead, while still enforcing every other launch guard: the campaign must have no step errors, any AI variables required by the campaign must be valid for the lead, and a sender must be available. No need to enable autolaunch in the campaign. This endpoint requires an `emailPro` plan or higher. via POST /leads/review/{leadId}

api
lemlist_post_leads_start_by_leadidWRITE

Resume Paused Lead via POST /leads/start/{leadId}

api
lemlist_post_lemwarm_by_usermailboxid_pauseWRITE

Pause lemwarm via POST /lemwarm/{userMailboxId}/pause

api
lemlist_post_lemwarm_by_usermailboxid_startWRITE

Start lemwarm via POST /lemwarm/{userMailboxId}/start

api
lemlist_post_schedulesWRITE

Create Schedule via POST /schedules

api
lemlist_post_sequences_by_sequenceid_stepsWRITE

Add Step to Sequence via POST /sequences/{sequenceId}/steps

api
lemlist_post_sequences_by_sequenceid_steps_by_stepid_ab_testWRITE

Creates variant B of an A/B test on a step, prefilled from variant A, and starts the test (leads are split between A and B). Supported on `email`, `linkedinInvite`, and `linkedinSend` steps. Requires the Email Pro plan. via POST /sequences/{sequenceId}/steps/{stepId}/ab-test

api
lemlist_post_sequences_by_sequenceid_steps_by_stepid_ab_test_winnerWRITE

Selects the winning variant of the A/B test. The winning template is then sent to all remaining leads going through the campaign. Requires the Email Pro plan. via POST /sequences/{sequenceId}/steps/{stepId}/ab-test/winner

api
lemlist_post_sequences_by_sequenceid_steps_by_stepid_branchesWRITE

Adds a branch to a condition step, just before the Else branch, and mints the empty sub-sequence it routes to. Add steps to that branch by calling `POST /sequences/{sequenceId}/steps` with the returned `sequenceId`. A branch carries the value it tests from the moment it is created - there are no blank branches - so the body must say what this one matches. The step's condition is shared by every branch and is never sent here: `conditionKey` in the body is refused. Only four conditions host several branches: `customLeadInfo`, `hasScore`, `hasEmailAddress` and `aircallDone`. Each needs its own tested value in the body, except `hasScore`, whose new branch inherits a complete `>= 80` band and can be added from an empty body. via POST /sequences/{sequenceId}/steps/{stepId}/branches

api
lemlist_post_tasksWRITE

Create a manual task (opportunity) associated with a contact/company or lead. via POST /tasks

api
lemlist_post_tasks_ignoreWRITE

Ignore Tasks via POST /tasks/ignore

api
lemlist_post_unsubscribes_by_emailWRITE

(deprecated) Add Unsubscribe Email or Domain via POST /unsubscribes/{email}

api
lemlist_post_user_email_accountsWRITE

Connect Email Account via POST /user/email-accounts

api
lemlist_post_user_email_accounts_by_emailaccountid_testWRITE

Test Email Account via POST /user/email-accounts/{emailAccountId}/test

api
lemlist_post_v2_campaigns_stats_batchWRITE

Retrieve detailed statistics for multiple campaigns in a single request, with filtering options by date, user, A/B testing, and communication channels. Processes up to 100 campaigns per request. via POST /v2/campaigns/stats/batch

api
lemlist_post_v2_enrichments_bulkWRITE

Send a batch of enrichment requests for multiple entities. Maximum 500 enrichment requests per call. via POST /v2/enrichments/bulk

api
lemlist_post_v2_unsubscribes_contacts_by_contactidWRITE

Marks a contact as unsubscribed (do-not-contact). via POST /v2/unsubscribes/contacts/{contactId}

api
lemlist_post_v2_unsubscribes_variablesWRITE

Unsubscribes up to 10,000 variables in a single request. via POST /v2/unsubscribes/variables

api
lemlist_post_v2_unsubscribes_variables_by_valueWRITE

Unsubscribes a single variable. This operation is idempotent — if the variable is already unsubscribed, the existing record is returned. via POST /v2/unsubscribes/variables/{value}

api
lemlist_post_watchlistWRITE

Create Signal Agent via POST /watchlist

api
lemlist_post_watchlist_by_watchlistid_external_signalsWRITE

Push external signals via POST /watchlist/{watchListId}/external-signals

api
lemlist_put_campaigns_by_campaignid_export_by_exportid_email_by_emailWRITE

Set an email address for a given export. When the export is done, an email with the download URL will be sent to the address provided. via PUT /campaigns/{campaignId}/export/{exportId}/email/{email}

api

Put lemlist behind one governed endpoint.

Same permissions, same audit trail, whatever else you connect next.