Every API here is available over the APIs.io API and to AI agents over MCP.
{
"openapi": "3.0.0",
"info": {
"title": "lemlist API",
"version": "1.0.0",
"description": "Welcome to the lemlist Developer Documentation.\n\nlemlist is very customizable and open. You'll find on this page all the API and integration you can do with lemlist.\n\n# Rate Limit\n\nlemlist's API rate limits requests in order to prevent abuse and overload of our services. \nRate limits are applied on all routes and per API key performing the request. \nThe rate limits are **20** requests per **2** seconds. \nThe response provides any information you may need about it:\n\n| Header | Description |\n| --- | --- |\n| Retry-After | The number of seconds in which you can retry |\n| X-RateLimit-Limit | The maximum requests in that time |\n| X-RateLimit-Remaining | The number of remaining requests you can make |\n| X-RateLimit-Reset | The date when the rate limit will reset |\n\n_Example of values for the rate limit headers_\n\n``` json\n{\n \"Retry-After\": 2,\n \"X-RateLimit-Limit\": 20,\n \"X-RateLimit-Remaining\": 7,\n \"X-RateLimit-Reset\" : \"Tue Feb 16 2021 09:02:42 GMT+0100 (Central European Standard Time)\"\n}\n\n ```\n\n# Definitions\n\n## Team\n\nA team is the entity of lemlist that can handle users and billing.\n\n## Credits\n\nCredits are the coins a team uses to enrich emails, LinkedIn URLs, etc. via the enrich route. Each enrichment feature needs a certain amount of credits to run.\n\n## User\n\nYou use a user account to connect to lemlist and send messages via the connected emails or LinkedIn account.\n\n## Campaign\n\nA campaign is the entity to automate outreach. A campaign has multiple sequences composed of steps.\n\n## Lead\n\nA lead is a person that you try to contact via a campaign.\n\n## Activity\n\nAn activity is the history of all the steps.\n\n## Unsubscribe\n\nAn unsubscribe occurs when a person decides they don't want to receive emails from you anymore.\n\n# Authentication\n\nAll API routes use the dedicated subdomain `api.lemlist.com`.\n\nlemlist uses API keys to allow access to the API. You can get your lemlist API key at our [integration page](https://app.lemlist.com/settings/integrations).\n\nYou need to add the `Authorization` header using the `Basic` authentication type. `login:password` **where the login is always empty and the password is the API key**.\n\n⚠️ **Don't forget to add the semicolon (**`:`**) before your API key in curl command.**\n\n> To authorize, use this code: \n \n\n``` shell\ncurl https://api.lemlist.com/api/team \\\n --user \":YourApiKey\"\n\n ```\n\n**Make sure to replace** **`YourApiKey`** **with your API key.**\n\n# Give feedback\n\nIf you want to report a bug, ask for data, or share with us a use case, please fill this [form](https://lemlist.typeform.com/to/mfVlkyGf). It will help us centralize your needs!"
},
"servers": [
{
"url": "https://api.lemlist.com/api"
}
],
"security": [
{
"basicAuth": []
}
],
"components": {
"securitySchemes": {
"basicAuth": {
"type": "http",
"scheme": "basic"
}
},
"schemas": {
"Team": {
"type": "object",
"description": "The organization account that manages users and billing.",
"properties": {
"_id": {
"type": "string",
"description": "Unique team identifier"
},
"name": {
"type": "string",
"description": "Team name"
},
"userIds": {
"type": "array",
"description": "User IDs in this team",
"items": {
"type": "string"
}
},
"createdBy": {
"type": "string",
"description": "User ID who created the team"
},
"createdAt": {
"type": "string",
"format": "date-time",
"description": "Date and time when the team was created"
},
"hooks": {
"type": "array",
"description": "Webhooks configured for the team",
"items": {
"$ref": "#/components/schemas/Webhook"
}
},
"beta": {
"type": "array",
"description": "Beta features enabled for the team",
"items": {
"type": "string"
}
},
"slackWebhook": {
"type": "object",
"properties": {
"url": {
"type": "string",
"format": "uri",
"description": "Slack webhook URL for notifications"
},
"failCounter": {
"type": "integer",
"description": "Number of consecutive failed notifications"
}
},
"description": "Slack webhooks configured for the team"
},
"invitedUsers": {
"type": "array",
"description": "Pending user invitations",
"items": {
"type": "object",
"properties": {
"email": {
"type": "string",
"format": "email"
},
"role": {
"type": "string"
},
"invitedBy": {
"type": "string"
},
"invitedAt": {
"type": "string",
"format": "date-time"
}
}
}
},
"agency": {
"type": "string",
"description": "Agency identifier if team is part of an agency"
},
"pictureId": {
"type": "string",
"description": "Team profile picture file ID"
},
"customDomain": {
"type": "string",
"description": "Custom domain for the team"
},
"users": {
"type": "array",
"description": "Team members with their basic details. Only returned when the request includes the `version=v2` query parameter.",
"items": {
"type": "object",
"properties": {
"userId": {
"type": "string",
"description": "Unique user identifier"
},
"name": {
"type": "string",
"description": "User's full name"
},
"email": {
"type": "string",
"format": "email",
"description": "User's primary email address"
},
"role": {
"type": "string",
"description": "User's role in the team"
}
}
}
}
}
},
"Credits": {
"type": "object",
"description": "Credits are the coins a team uses to enrich emails, LinkedIn URLs, etc. Each enrichment feature needs a certain amount of credits to run.",
"properties": {
"credits": {
"type": "integer",
"description": "Total credits remaining"
},
"details": {
"type": "object",
"properties": {
"remaining": {
"type": "object",
"properties": {
"total": {
"type": "integer",
"description": "Total credits remaining"
},
"freemium": {
"type": "integer",
"description": "Freemium credits remaining"
},
"subscription": {
"type": "integer",
"description": "Subscription credits remaining"
},
"gifted": {
"type": "integer",
"description": "Gifted credits remaining"
},
"paid": {
"type": "integer",
"description": "Paid credits remaining"
}
}
}
}
}
}
},
"User": {
"type": "object",
"description": "A team member account with connected email and/or LinkedIn sending capabilities.",
"properties": {
"_id": {
"type": "string",
"description": "Unique user identifier"
},
"email": {
"type": "string",
"format": "email",
"description": "User email address"
},
"role": {
"type": "string",
"description": "User role in the team (admin, member, etc.)"
},
"linkedIn": {
"type": "object",
"description": "LinkedIn integration settings",
"properties": {
"linkedinUrl": {
"type": "string",
"description": "The LinkedIn URL of the person"
},
"status": {
"type": "boolean",
"description": "Whether LinkedIn is connected"
},
"inviteLimit": {
"type": "integer",
"description": "Daily limit for LinkedIn connection invites"
},
"sendLimit": {
"type": "integer",
"description": "Daily limit for LinkedIn messages"
},
"visitLimit": {
"type": "integer",
"description": "Daily limit for LinkedIn profile visits"
}
}
},
"mailboxes": {
"type": "array",
"description": "Email mailboxes connected to this user",
"items": {
"$ref": "#/components/schemas/Mailbox"
}
}
}
},
"Campaign": {
"type": "object",
"description": "An automated outreach workflow containing sequences of steps.",
"properties": {
"_id": {
"type": "string",
"description": "Unique campaign identifier"
},
"name": {
"type": "string",
"description": "Campaign name"
},
"emoji": {
"type": "string",
"description": "Emoji shown next to the campaign name"
},
"labels": {
"type": "array",
"description": "Categorization labels",
"items": {
"type": "string"
}
},
"createdAt": {
"type": "string",
"format": "date-time",
"description": "Creation timestamp"
},
"createdBy": {
"type": "string",
"description": "Creator user ID"
},
"status": {
"type": "string",
"description": "Campaign status",
"enum": [
"running",
"paused",
"draft",
"ended",
"archived",
"errors"
]
},
"sequenceId": {
"type": "string",
"description": "Main sequence ID"
},
"scheduleIds": {
"type": "array",
"description": "Associated schedule IDs",
"items": {
"type": "string"
}
},
"timezone": {
"type": "string",
"description": "IANA timezone the campaign schedule runs in (e.g. \"Europe/Paris\")"
},
"teamId": {
"type": "string",
"description": "ID of the team that owns this campaign"
},
"hasError": {
"type": "boolean",
"description": "Whether the campaign has errors"
},
"errors": {
"type": "array",
"description": "List of error messages if campaign has errors",
"items": {
"type": "string"
}
},
"creator": {
"type": "object",
"description": "Campaign creator information",
"properties": {
"userId": {
"type": "string",
"description": "Creator user ID"
},
"userEmail": {
"type": "string",
"format": "email",
"description": "Creator email address"
}
}
},
"senders": {
"type": "array",
"description": "Campaign senders configuration",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string",
"description": "Sender user ID"
},
"email": {
"type": "string",
"format": "email",
"description": "Sender email address"
},
"sendUserMailboxId": {
"type": "string",
"description": "Mailbox ID used for sending"
}
}
}
}
}
},
"Lead": {
"type": "object",
"description": "A contact added to a campaign for outreach. Not to be confused with a contact which is a record in lemlist, but not necessarily added to a campaign.",
"properties": {
"_id": {
"type": "string",
"description": "Unique lead identifier"
},
"email": {
"type": "string",
"format": "email",
"description": "Lead email address"
},
"firstName": {
"type": "string",
"description": "First name"
},
"lastName": {
"type": "string",
"description": "Last name"
},
"companyName": {
"type": "string",
"description": "Company name"
},
"phone": {
"type": "string",
"description": "Phone number"
},
"linkedinUrl": {
"type": "string",
"format": "uri",
"description": "LinkedIn profile URL"
},
"picture": {
"type": "string",
"format": "uri",
"description": "Profile picture URL"
},
"icebreaker": {
"type": "string",
"description": "Personalized icebreaker text"
},
"timezone": {
"type": "string",
"description": "Lead's timezone in IANA format (e.g., Europe/Paris, America/New_York)"
},
"campaignId": {
"type": "string",
"description": "Campaign ID the lead belongs to"
},
"campaignName": {
"type": "string",
"description": "Campaign name the lead belongs to"
},
"isUnsubscribed": {
"type": "boolean",
"description": "Whether the lead is unsubscribed"
}
}
},
"Activity": {
"type": "object",
"description": "A recorded action or event in a campaign sequence (email sent, opened, clicked, etc.).",
"properties": {
"_id": {
"type": "string",
"description": "Unique activity identifier"
},
"type": {
"type": "string",
"description": "Activity type (emailOpened, emailClicked, emailReplied, etc.)"
},
"leadId": {
"type": "string",
"description": "Associated lead ID"
},
"campaignId": {
"type": "string",
"description": "Campaign ID"
},
"sequenceId": {
"type": "string",
"description": "Sequence ID"
},
"stepId": {
"type": "string",
"description": "Stable identifier of the sequence step that produced this activity. Present on every activity created from now on; older activities gain it progressively as historical records are backfilled, so treat it as optional when reading history."
},
"sequenceStep": {
"type": "number",
"description": "0-based position of the step within the sequence. Still emitted on every activity, unchanged. Prefer `stepId` for a reference that survives steps being reordered."
},
"totalSequenceStep": {
"type": "number",
"description": "0-based count of the sequence steps already delivered to this lead."
},
"createdAt": {
"type": "string",
"format": "date-time",
"description": "When the activity occurred"
}
}
},
"Unsubscribe": {
"type": "object",
"description": "A record of someone opting out of receiving emails.",
"properties": {
"_id": {
"type": "string",
"description": "Unique unsubscribe identifier"
},
"email": {
"type": "string",
"format": "email",
"description": "Unsubscribed email address"
},
"campaignId": {
"type": "string",
"description": "Campaign ID from which the person unsubscribed"
},
"campaignName": {
"type": "string",
"description": "Campaign name from which the person unsubscribed"
},
"unsubscribedAt": {
"type": "string",
"format": "date-time",
"description": "Unsubscribe timestamp"
},
"scope": {
"type": "string",
"description": "Unsubscribe scope",
"enum": [
"campaign",
"team",
"global"
]
}
}
},
"UnsubscribedVariable": {
"type": "object",
"description": "A variable (email, domain, LinkedIn URL, or phone number) that has been unsubscribed.",
"properties": {
"_id": {
"type": "string",
"description": "Unique identifier for the unsubscribe entry"
},
"value": {
"type": "string",
"description": "The unsubscribed variable (email, domain, LinkedIn URL, or phone number)"
},
"source": {
"type": "string",
"description": "Origin of the unsubscription",
"enum": [
"api",
"bounced",
"lead",
"user",
"abuse"
]
},
"createdAt": {
"type": "string",
"format": "date-time",
"description": "When the variable was unsubscribed"
}
}
},
"ContactSubscriptionStatus": {
"type": "object",
"description": "Subscription status of a contact.",
"properties": {
"_id": {
"type": "string",
"description": "Contact identifier"
},
"doNotContact": {
"type": "boolean",
"description": "Whether the contact is unsubscribed"
}
}
},
"Enrich": {
"type": "object",
"description": "Contact information discovered through data enrichment (emails, phone numbers, LinkedIn URLs).",
"properties": {
"_id": {
"type": "string",
"description": "Unique enrichment request identifier"
},
"status": {
"type": "string",
"description": "Enrichment status",
"enum": [
"pending",
"completed",
"failed"
]
},
"email": {
"type": "string",
"format": "email",
"description": "Found email address"
},
"phone": {
"type": "string",
"description": "Found phone number"
},
"firstName": {
"type": "string",
"description": "Found first name"
},
"lastName": {
"type": "string",
"description": "Found last name"
},
"companyName": {
"type": "string",
"description": "Found company name"
},
"linkedinUrl": {
"type": "string",
"format": "uri",
"description": "Found LinkedIn URL"
},
"credits": {
"type": "integer",
"description": "Credits consumed"
}
}
},
"Task": {
"type": "object",
"description": "A manual action assigned to a user to complete.",
"properties": {
"_id": {
"type": "string",
"description": "Unique task identifier"
},
"type": {
"type": "string",
"description": "Task type"
},
"leadId": {
"type": "string",
"description": "Associated lead ID"
},
"campaignId": {
"type": "string",
"description": "Campaign ID"
},
"userId": {
"type": "string",
"description": "Assigned user ID"
},
"status": {
"type": "string",
"description": "Task status",
"enum": [
"pending",
"completed",
"ignored"
]
},
"dueDate": {
"type": "string",
"format": "date-time",
"description": "Due date timestamp"
},
"createdAt": {
"type": "string",
"format": "date-time",
"description": "Creation timestamp"
},
"completedAt": {
"type": "string",
"format": "date-time",
"description": "Completion timestamp"
}
}
},
"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": {
"type": "string"
},
"campaignState": {
"type": "string"
},
"leadState": {
"type": "string"
},
"leadId": {
"type": "string"
}
}
}
},
"ownerId": {
"type": "string",
"description": "ID of the user who owns this contact"
},
"createdAt": {
"type": "string",
"format": "date-time",
"description": "Contact creation timestamp"
},
"createdBy": {
"type": "string",
"description": "ID of the user who created the contact"
},
"unsubscribed": {
"type": "boolean",
"description": "Whether the contact is globally unsubscribed. When true, no outreach will be sent to this contact."
},
"fieldRejections": {
"type": "array",
"description": "Values lemlist refused to write on this contact, each with its reason. Empty when none. Filter the list endpoint to only flagged contacts via `GET /contacts?fieldRejectionReason=...`.",
"items": {
"$ref": "#/components/schemas/FieldRejection"
}
}
}
},
"Company": {
"type": "object",
"description": "An organization record in your CRM.",
"properties": {
"_id": {
"type": "string",
"description": "Unique company identifier"
},
"name": {
"type": "string",
"description": "Company name (may also be present under fields.name)"
},
"domain": {
"type": "string",
"description": "Website domain"
},
"industry": {
"type": "string",
"description": "Industry sector"
},
"size": {
"type": "string",
"description": "Company size"
},
"location": {
"type": "string",
"description": "Geographic location"
},
"fields": {
"type": "object",
"description": "Flexible key/value fields of the company (e.g., name, picture, industry, location, size, foundedOn)",
"additionalProperties": true
},
"createdBy": {
"type": "string",
"description": "User ID who created the company"
},
"ownerId": {
"type": "string",
"description": "User ID of the owner of the company"
},
"createdAt": {
"type": "string",
"format": "date-time",
"description": "Creation timestamp"
},
"fieldRejections": {
"type": "array",
"description": "Values lemlist refused to write on this company, each with its reason. Empty when none. Filter the list endpoint to only flagged companies via `GET /companies?fieldRejectionReason=...`.",
"items": {
"$ref": "#/components/schemas/FieldRejection"
}
},
"crmSync": {
"type": "object",
"nullable": true,
"description": "CRM sync status for the company, resolved against the team's active CRM provider (Hubspot, Salesforce, or Pipedrive). Only present when a CRM is connected. Use this block to monitor sync state and resolve duplicates (e.g. via `GET /companies?crmSyncStatus=unique_index_error_company`).",
"properties": {
"provider": {
"type": "string",
"enum": [
"hubspot",
"salesforce",
"pipedrive"
],
"description": "Active CRM provider for the team."
},
"crmRecordId": {
"type": "string",
"nullable": true,
"description": "Identifier of the company record on the CRM side. `null` when the lemlist company has not been synced yet."
},
"syncDisabled": {
"type": "boolean",
"description": "When `true`, automatic sync is paused for this company."
},
"errors": {
"type": "array",
"description": "List of recent sync errors. Empty when the company is synced cleanly.",
"items": {
"type": "object",
"properties": {
"type": {
"type": "string",
"description": "Coarse error category (e.g. `CONNECT_FAILED`, `CREATE_FAILED`, `UPDATE_FAILED`)."
},
"reason": {
"type": "string",
"description": "Specific error reason. Matches the lowercase form accepted by the `crmSyncStatus` query param (e.g. `UNIQUE_INDEX_ERROR_COMPANY`, `PROPERTY_DOESNT_EXIST`, `REQUIRED_FIELD_MISSING`)."
},
"raisedAt": {
"type": "string",
"format": "date-time",
"description": "Timestamp when the error was last raised."
},
"metadata": {
"type": "object",
"additionalProperties": true,
"description": "Extra context. For `UNIQUE_INDEX_ERROR_COMPANY`, contains `alreadyExistingCompanyId` — the lemlist company that already occupies the conflicting CRM record. Use it to remap contacts onto the right lemlist company before deleting the duplicate."
}
}
}
}
}
}
}
},
"DatabaseCompany": {
"type": "object",
"description": "A company record from lemlist's People database.",
"properties": {
"company_id": {
"type": "integer",
"description": "Unique company identifier"
},
"company_name": {
"type": "string",
"description": "Company name"
},
"company_website_url": {
"type": "string",
"description": "Website URL"
},
"company_employee_count": {
"type": "integer",
"description": "Employee count"
},
"company_industry": {
"type": "string",
"description": "Industry sector"
}
}
},
"CompanyNote": {
"type": "object",
"description": "A text note attached to a company record to store information.",
"properties": {
"_id": {
"type": "string",
"description": "Unique note identifier"
},
"teamId": {
"type": "string",
"description": "Team ID that owns the company"
},
"companyId": {
"type": "string",
"description": "Parent company ID"
},
"note": {
"type": "string",
"description": "Note text content"
},
"type": {
"type": "string",
"description": "Type of note or activity (e.g., 'annotated')"
},
"userId": {
"type": "string",
"description": "ID of the user who created the note"
},
"sendUserId": {
"type": "string",
"description": "ID of the send
# --- truncated at 32 KB (768 KB total) ---
# Full source: https://raw.githubusercontent.com/api-evangelist/lemlist/refs/heads/main/openapi/_original/lemlist-openapi-v2.json