Lemlist
Verified@byungkyu
npx machina-cli add skill @byungkyu/lemlist --openclawLemlist
Access the Lemlist API with managed OAuth authentication. Manage campaigns, leads, activities, schedules, sequences, and unsubscribes for sales automation and cold outreach.
Quick Start
# List campaigns
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://gateway.maton.ai/lemlist/api/campaigns')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
Base URL
https://gateway.maton.ai/lemlist/api/{resource}
Replace {resource} with the actual Lemlist API endpoint path. The gateway proxies requests to api.lemlist.com/api and automatically injects your OAuth token.
Authentication
All requests require the Maton API key in the Authorization header:
Authorization: Bearer $MATON_API_KEY
Environment Variable: Set your API key as MATON_API_KEY:
export MATON_API_KEY="YOUR_API_KEY"
Getting Your API Key
- Sign in or create an account at maton.ai
- Go to maton.ai/settings
- Copy your API key
Connection Management
Manage your Lemlist OAuth connections at https://ctrl.maton.ai.
List Connections
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://ctrl.maton.ai/connections?app=lemlist&status=ACTIVE')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
Create Connection
python <<'EOF'
import urllib.request, os, json
data = json.dumps({'app': 'lemlist'}).encode()
req = urllib.request.Request('https://ctrl.maton.ai/connections', data=data, method='POST')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
req.add_header('Content-Type', 'application/json')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
Get Connection
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://ctrl.maton.ai/connections/{connection_id}')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
Response:
{
"connection": {
"connection_id": "3ecf268f-42ad-40cc-b77a-25e020fbf591",
"status": "ACTIVE",
"creation_time": "2026-02-12T02:00:53.023887Z",
"last_updated_time": "2026-02-12T02:01:45.284131Z",
"url": "https://connect.maton.ai/?session_token=...",
"app": "lemlist",
"metadata": {}
}
}
Open the returned url in a browser to complete OAuth authorization.
Delete Connection
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://ctrl.maton.ai/connections/{connection_id}', method='DELETE')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
Specifying Connection
If you have multiple Lemlist connections, specify which one to use with the Maton-Connection header:
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://gateway.maton.ai/lemlist/api/campaigns')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
req.add_header('Maton-Connection', '3ecf268f-42ad-40cc-b77a-25e020fbf591')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
If omitted, the gateway uses the default (oldest) active connection.
API Reference
Team
Get Team
GET /lemlist/api/team
Returns team information including user IDs and settings.
Get Team Credits
GET /lemlist/api/team/credits
Returns remaining credits balance.
Get Team Senders
GET /lemlist/api/team/senders
Returns all team members and their associated campaigns.
Campaigns
List Campaigns
GET /lemlist/api/campaigns
Create Campaign
POST /lemlist/api/campaigns
Content-Type: application/json
{
"name": "My Campaign"
}
Creates a new campaign with an empty sequence and default schedule automatically added.
Get Campaign
GET /lemlist/api/campaigns/{campaignId}
Update Campaign
PATCH /lemlist/api/campaigns/{campaignId}
Content-Type: application/json
{
"name": "Updated Campaign Name"
}
Pause Campaign
POST /lemlist/api/campaigns/{campaignId}/pause
Pauses a running campaign.
Campaign Sequences
Get Campaign Sequences
GET /lemlist/api/campaigns/{campaignId}/sequences
Returns all sequences and steps for a campaign.
Campaign Schedules
Get Campaign Schedules
GET /lemlist/api/campaigns/{campaignId}/schedules
Returns all schedules associated with a campaign.
Leads
Add Lead to Campaign
POST /lemlist/api/campaigns/{campaignId}/leads
Content-Type: application/json
{
"email": "lead@example.com",
"firstName": "John",
"lastName": "Doe",
"companyName": "Acme Inc"
}
Creates a new lead and adds it to the campaign. If the lead already exists, it will be inserted into the campaign.
Get Lead by Email
GET /lemlist/api/leads/{email}
Update Lead in Campaign
PATCH /lemlist/api/campaigns/{campaignId}/leads/{email}
Content-Type: application/json
{
"firstName": "Jane",
"lastName": "Smith"
}
Delete Lead from Campaign
DELETE /lemlist/api/campaigns/{campaignId}/leads/{email}
Activities
List Activities
GET /lemlist/api/activities
Returns the history of campaign activities (last 100 activities).
Query parameters:
campaignId- Filter by campaigntype- Filter by activity type (emailsSent, emailsOpened, emailsClicked, etc.)
Schedules
List Schedules
GET /lemlist/api/schedules
Returns all schedules with pagination.
Response:
{
"schedules": [...],
"pagination": {
"totalRecords": 10,
"currentPage": 1,
"nextPage": 2,
"totalPage": 2
}
}
Create Schedule
POST /lemlist/api/schedules
Content-Type: application/json
{
"name": "Business Hours",
"timezone": "America/New_York",
"start": "09:00",
"end": "17:00",
"weekdays": [1, 2, 3, 4, 5]
}
Weekdays: 0 = Sunday, 1 = Monday, ..., 6 = Saturday
Get Schedule
GET /lemlist/api/schedules/{scheduleId}
Update Schedule
PATCH /lemlist/api/schedules/{scheduleId}
Content-Type: application/json
{
"name": "Updated Schedule",
"start": "08:00",
"end": "18:00"
}
Delete Schedule
DELETE /lemlist/api/schedules/{scheduleId}
Companies
List Companies
GET /lemlist/api/companies
Returns companies with pagination.
Response:
{
"data": [...],
"total": 100
}
Unsubscribes
List Unsubscribes
GET /lemlist/api/unsubscribes
Returns all unsubscribed emails and domains.
Add Unsubscribe
POST /lemlist/api/unsubscribes
Content-Type: application/json
{
"email": "unsubscribe@example.com"
}
Can also add domains by using a domain value.
Inbox Labels
List Labels
GET /lemlist/api/inbox/labels
Returns all labels available to the team.
Pagination
Lemlist uses page-based pagination with different formats depending on the endpoint:
Schedules format:
{
"schedules": [...],
"pagination": {
"totalRecords": 100,
"currentPage": 1,
"nextPage": 2,
"totalPage": 10
}
}
Companies format:
{
"data": [...],
"total": 100
}
Code Examples
JavaScript - List Campaigns
const response = await fetch(
'https://gateway.maton.ai/lemlist/api/campaigns',
{
headers: {
'Authorization': `Bearer ${process.env.MATON_API_KEY}`
}
}
);
const campaigns = await response.json();
console.log(campaigns);
Python - List Campaigns
import os
import requests
response = requests.get(
'https://gateway.maton.ai/lemlist/api/campaigns',
headers={'Authorization': f'Bearer {os.environ["MATON_API_KEY"]}'}
)
campaigns = response.json()
for campaign in campaigns:
print(f"{campaign['name']}: {campaign['_id']}")
Python - Create Campaign and Add Lead
import os
import requests
headers = {'Authorization': f'Bearer {os.environ["MATON_API_KEY"]}'}
base_url = 'https://gateway.maton.ai/lemlist/api'
# Create campaign
campaign_response = requests.post(
f'{base_url}/campaigns',
headers=headers,
json={'name': 'Q1 Outreach'}
)
campaign = campaign_response.json()
print(f"Created campaign: {campaign['_id']}")
# Add lead to campaign
lead_response = requests.post(
f'{base_url}/campaigns/{campaign["_id"]}/leads',
headers=headers,
json={
'email': 'prospect@example.com',
'firstName': 'John',
'lastName': 'Doe',
'companyName': 'Acme Corp'
}
)
lead = lead_response.json()
print(f"Added lead: {lead['_id']}")
Notes
- Campaign IDs start with
cam_ - Lead IDs start with
lea_ - Schedule IDs start with
skd_ - Sequence IDs start with
seq_ - Team IDs start with
tea_ - User IDs start with
usr_ - Campaigns cannot be deleted via API (only paused)
- When creating a campaign, an empty sequence and default schedule are automatically added
- Lead emails are used as identifiers for lead operations
- IMPORTANT: When using curl commands, use
curl -gwhen URLs contain brackets to disable glob parsing - IMPORTANT: When piping curl output to
jq, environment variables may not expand correctly. Use Python examples instead.
Rate Limits
| Operation | Limit |
|---|---|
| API calls | 20 per 2 seconds per API key |
When rate limited, implement exponential backoff for retries.
Error Handling
| Status | Meaning |
|---|---|
| 400 | Bad request or missing Lemlist connection |
| 401 | Invalid or missing Maton API key |
| 404 | Resource not found |
| 405 | Method not allowed |
| 422 | Validation error |
| 429 | Rate limited |
| 4xx/5xx | Passthrough error from Lemlist API |
Troubleshooting: API Key Issues
- Check that the
MATON_API_KEYenvironment variable is set:
echo $MATON_API_KEY
- Verify the API key is valid by listing connections:
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://ctrl.maton.ai/connections')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
Troubleshooting: Invalid App Name
- Ensure your URL path starts with
lemlist. For example:
- Correct:
https://gateway.maton.ai/lemlist/api/campaigns - Incorrect:
https://gateway.maton.ai/api/campaigns
Resources
Overview
Provides OAuth-protected access to Lemlist via a gateway. Manage campaigns, leads, activities, schedules, sequences, and unsubscribes through a single API surface. The gateway proxies to api.lemlist.com/api and injects your OAuth token for seamless authentication.
How This Skill Works
Requests target https://gateway.maton.ai/lemlist/api/{resource}. The gateway forwards these requests to Lemlist (api.lemlist.com/api) and automatically injects your OAuth token. All calls require MATON_API_KEY in the Authorization header, and you can select a specific OAuth connection with the Maton-Connection header if needed; manage connections at ctrl.maton.ai.
When to Use It
- When you need to manage Lemlist campaigns, leads, activities, or schedules from a unified API surface.
- When you want to perform unsubscribes operations or handle sequences via the API gateway.
- When integrating Lemlist with other tools using a centralized gateway (instead of direct Lemlist endpoints).
- When you need to share access across environments by using the Maton-Connection header to pick a specific OAuth connection.
- When debugging authentication flow or migrating existing Lemlist automation to Maton’s gateway.
Quick Start
- Step 1: export MATON_API_KEY and set it in your environment.
- Step 2: call a resource, e.g., GET https://gateway.maton.ai/lemlist/api/campaigns with Authorization: Bearer $MATON_API_KEY.
- Step 3: if you have multiple Lemlist connections, add Maton-Connection: <connection_id> to your request and manage connections at ctrl.maton.ai.
Best Practices
- Store and protect MATON_API_KEY securely; use environment variables and secret management.
- Use the base URL pattern /lemlist/api/{resource} and validate the resource path before calling.
- If multiple Lemlist connections exist, include Maton-Connection to target the right one.
- Audit and paginate responses for large datasets (handle next-page tokens if provided).
- Test changes in a development environment before deploying to production; rotate API keys regularly.
Example Use Cases
- List all campaigns: GET https://gateway.maton.ai/lemlist/api/campaigns with Authorization: Bearer $MATON_API_KEY.
- Create or update a lead in Lemlist via POST /lemlist/api/leads with lead data.
- Retrieve upcoming schedules via GET /lemlist/api/schedules and filter by status.
- Unsubscribe a contact using POST /lemlist/api/unsubscribes with the contact identifier.
- List active connections and switch context using the Maton-Connection header in requests.