- name
- instantly
- description
- |
- compatibility
- Requires network access and valid Maton API key
- metadata
- author
- maton
- version
- 1.0
- clawdbot
- emoji
- 🧠
- homepage
- https://maton.ai
- requires
- env
Instantly
Access the Instantly API v2 with managed authentication. Manage cold email campaigns, leads, sending accounts, and view analytics.
Quick Start
# List campaigns
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.maton.ai/instantly/api/v2/campaigns?limit=10')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOFBase URL
https://api.maton.ai/instantly/{native-api-path}Maton proxies requests to api.instantly.ai and automatically injects your API key.
Authentication
All requests require the Maton API key in the Authorization header:
Authorization: Bearer $MATON_API_KEYEnvironment 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 Instantly connections at https://api.maton.ai.
List Connections
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.maton.ai/connections?app=instantly&status=ACTIVE')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOFCreate Connection
python <<'EOF'
import urllib.request, os, json
data = json.dumps({'app': 'instantly'}).encode()
req = urllib.request.Request('https://api.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))
EOFGet Connection
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.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))
EOFResponse:
{
"connection": {
"connection_id": "{connection_id}",
"status": "ACTIVE",
"creation_time": "2026-02-11T22:19:35.798712Z",
"last_updated_time": "2026-02-11T22:20:15.702846Z",
"url": "https://connect.maton.ai/?session_token=...",
"app": "instantly",
"metadata": {}
}
}Open the returned url in a browser to complete authorization.
Delete Connection
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.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))
EOFSpecifying Connection
If you have multiple Instantly connections, specify which one to use with the Maton-Connection header:
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.maton.ai/instantly/api/v2/campaigns')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
req.add_header('Maton-Connection', '{connection_id}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOFIf you have multiple connections, always include this header to ensure requests go to the intended account.
Security & Permissions
- Access is scoped to campaigns, leads, accounts, and email analytics within the connected Instantly account.
- All write operations require explicit user approval. Before executing any create, update, or delete call, confirm the target resource and intended effect with the user.
API Reference
Campaigns
List Campaigns
GET /instantly/api/v2/campaigns?limit=10&status=1&search=keywordQuery parameters:
limit- Number of results (default: 10)status- Campaign status filter (0=draft, 1=active, 2=paused, 3=completed)search- Search by campaign namestarting_after- Cursor for pagination
Get Campaign
GET /instantly/api/v2/campaigns/{campaign_id}Create Campaign
POST /instantly/api/v2/campaigns
Content-Type: application/json
{
"name": "My Campaign",
"campaign_schedule": {
"schedules": [
{
"name": "My Schedule",
"timing": {
"from": "09:00",
"to": "17:00"
},
"days": {
"0": true,
"1": true,
"2": true,
"3": true,
"4": true
},
"timezone": "Etc/GMT+5"
}
]
}
}Note: Timezone must use Etc/GMT format (e.g., "Etc/GMT+5", "Etc/GMT-8", "Etc/GMT+12").
#### Activate Campaign
POST /instantly/api/v2/campaigns/{campaign_id}/activate
#### Pause Campaign
POST /instantly/api/v2/campaigns/{campaign_id}/pause
#### Delete Campaign
DELETE /instantly/api/v2/campaigns/{campaign_id}
#### Search Campaigns by Lead Email
GET /instantly/api/v2/campaigns/search-by-contact?search=lead@example.com
### Leads
#### Create Lead
POST /instantly/api/v2/leads Content-Type: application/json
{ "campaign_id": "019bb3bd-9963-789e-b776-6c6927ef3f79", "email": "lead@example.com", "first_name": "John", "last_name": "Doe", "company_name": "Acme Inc", "variables": { "custom_field": "custom_value" } }
#### Bulk Add Leads
POST /instantly/api/v2/leads Content-Type: application/json
{ "campaign_id": "019bb3bd-9963-789e-b776-6c6927ef3f79", "leads": [ { "email": "lead1@example.com", "first_name": "John" }, { "email": "lead2@example.com", "first_name": "Jane" } ] }
#### List Leads
Note: This is a POST endpoint due to complex filtering requirements.
POST /instantly/api/v2/leads/list Content-Type: application/json
{ "campaign_id": "019bb3bd-9963-789e-b776-6c6927ef3f79", "limit": 100 }
#### Get Lead
GET /instantly/api/v2/leads/{lead_id}
#### Delete Lead
DELETE /instantly/api/v2/leads/{lead_id}
#### Move Leads
POST /instantly/api/v2/leads/move Content-Type: application/json
{ "lead_ids": ["lead_id_1", "lead_id_2"], "to_campaign_id": "target_campaign_id" }
### Lead Lists
#### List Lead Lists
GET /instantly/api/v2/lead-lists?limit=10
#### Create Lead List
POST /instantly/api/v2/lead-lists Content-Type: application/json
{ "name": "My Lead List" }
#### Get Lead List
GET /instantly/api/v2/lead-lists/{list_id}
#### Update Lead List
PATCH /instantly/api/v2/lead-lists/{list_id} Content-Type: application/json
{ "name": "Updated List Name" }
#### Delete Lead List
DELETE /instantly/api/v2/lead-lists/{list_id}
### Accounts (Sending Email Accounts)
#### List Accounts
GET /instantly/api/v2/accounts?limit=10
#### Get Account
GET /instantly/api/v2/accounts/{email}
#### Create Account
POST /instantly/api/v2/accounts Content-Type: application/json
{ "email": "sender@example.com", "first_name": "John", "last_name": "Doe", "provider_code": "google", "smtp_host": "smtp.gmail.com", "smtp_port": 587, "smtp_username": "sender@example.com", "smtp_password": "app_password", "imap_host": "imap.gmail.com", "imap_port": 993, "imap_username": "sender@example.com", "imap_password": "app_password" }
#### Update Account
PATCH /instantly/api/v2/accounts/{email} Content-Type: application/json
{ "first_name": "Jane" }
#### Delete Account
DELETE /instantly/api/v2/accounts/{email}
#### Enable Warmup
POST /instantly/api/v2/accounts/warmup/enable Content-Type: application/json
{ "emails": ["account1@example.com", "account2@example.com"] }
#### Disable Warmup
POST /instantly/api/v2/accounts/warmup/disable Content-Type: application/json
{ "emails": ["account1@example.com"] }
### Emails (Unibox)
#### List Emails
GET /instantly/api/v2/emails?limit=20
#### Get Email
GET /instantly/api/v2/emails/{email_id}
#### Reply to Email
POST /instantly/api/v2/emails/reply Content-Type: application/json
{ "reply_to_uuid": "email_uuid", "body": "Thank you for your response!" }
#### Forward Email
POST /instantly/api/v2/emails/forward Content-Type: application/json
{ "email_uuid": "email_uuid", "to": "forward@example.com" }
#### Mark Thread as Read
POST /instantly/api/v2/emails/threads/{thread_id}/mark-as-read
#### Get Unread Count
GET /instantly/api/v2/emails/unread/count
#### Update Email
PATCH /instantly/api/v2/emails/{email_id} Content-Type: application/json
{ "is_read": true }
#### Delete Email
DELETE /instantly/api/v2/emails/{email_id}
### Analytics
#### Get Campaign Analytics
GET /instantly/api/v2/campaigns/analytics?id={campaign_id}
Query parameters:
- `id` - Campaign ID (leave empty for all campaigns)
- `start_date` - Filter start date (YYYY-MM-DD)
- `end_date` - Filter end date (YYYY-MM-DD)
- `exclude_total_leads_count` - Set to true for faster response
#### Get Campaign Analytics Overview
GET /instantly/api/v2/campaigns/analytics/overview?id={campaign_id}
#### Get Daily Campaign Analytics
GET /instantly/api/v2/campaigns/analytics/daily?id={campaign_id}
#### Get Campaign Step Analytics
GET /instantly/api/v2/campaigns/analytics/steps?id={campaign_id}
#### Get Warmup Analytics
POST /instantly/api/v2/accounts/warmup/analytics Content-Type: application/json
{ "emails": ["account@example.com"] }
### Block List
#### List Block List Entries
GET /instantly/api/v2/block-lists-entries?limit=100
Query parameters:
- `domains_only` - Filter to domain entries only
- `search` - Search entries
#### Create Block List Entry
POST /instantly/api/v2/block-lists-entries Content-Type: application/json
{ "bl_value": "blocked@example.com" }
Or block a domain:
POST /instantly/api/v2/block-lists-entries Content-Type: application/json
{ "bl_value": "blockeddomain.com" }
#### Delete Block List Entry
DELETE /instantly/api/v2/block-lists-entries/{entry_id}
### Email Verification
#### Verify Email
GET /instantly/api/v2/email-verification/{email}
If verification takes longer than 10 seconds, status will be `pending`. Poll this endpoint to check status.
Response fields:
- `verification_status` - Use this field (not `status`) to determine verification result
### Background Jobs
#### Get Background Job Status
GET /instantly/api/v2/background-jobs/{job_id}
Query parameters:
- `data_fields` - Comma-separated fields (e.g., `success_count,failed_count,total_to_process`)
### Workspace
#### Get Current Workspace
GET /instantly/api/v2/workspaces/current
### Custom Tags
#### Toggle Tag on Resource
POST /instantly/api/v2/custom-tags/toggle-resource Content-Type: application/json
{ "tag_id": "tag_uuid", "resource_id": "campaign_or_account_id", "resource_type": "campaign" }
## Pagination
Instantly uses cursor-based pagination with `limit` and `starting_after`:
GET /instantly/api/v2/campaigns?limit=10&starting_after=cursor_value
Response includes pagination info:
{ "items": [...], "next_starting_after": "cursor_for_next_page" }
Use `next_starting_after` value in the next request's `starting_after` parameter.
## Code Examples
### JavaScript
const response = await fetch( 'https://api.maton.ai/instantly/api/v2/campaigns?limit=10', { headers: { 'Authorization': Bearer ${process.env.MATON_API_KEY} } } ); const data = await response.json();
### Python
import os import requests
response = requests.get( 'https://api.maton.ai/instantly/api/v2/campaigns', headers={'Authorization': f'Bearer {os.environ["MATON_API_KEY"]}'}, params={'limit': 10} ) data = response.json()
## Notes
- Instantly API v2 uses snake_case for all field names
- Lead custom variables must be string, number, boolean, or null (no objects/arrays)
- The List Leads endpoint is POST (not GET) due to complex filtering requirements
- Campaign status values: 0=draft, 1=active, 2=paused, 3=completed
- Email verification may return `pending` status if it takes longer than 10 seconds
- Warmup operations return background job IDs - poll the background jobs endpoint for status
- IMPORTANT: When using curl commands, use `curl -g` when URLs contain brackets to disable glob parsing
- IMPORTANT: When piping curl output to `jq`, environment variables may not expand correctly. Use Python examples instead.
## Error Handling
| Status | Meaning |
|--------|---------|
| 400 | Missing Instantly connection or invalid request |
| 401 | Invalid or missing Maton API key |
| 403 | Insufficient API key scopes |
| 429 | Rate limited |
| 4xx/5xx | Passthrough error from Instantly API |
### Troubleshooting: API Key Issues
1. Check that the `MATON_API_KEY` environment variable is set:
echo $MATON_API_KEY
2. Verify the API key is valid by listing connections:
python <<'EOF' import urllib.request, os, json req = urllib.request.Request('https://api.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
1. Ensure your URL path starts with `instantly`. For example:
- Correct: `https://api.maton.ai/instantly/api/v2/campaigns`
- Incorrect: `https://api.maton.ai/api/v2/campaigns`
## Resources
- [Instantly API V2 Documentation](https://developer.instantly.ai/api/v2)
- [Instantly API Introduction](https://developer.instantly.ai/)
- [Instantly Help Center](https://help.instantly.ai/)
- [Maton Community](https://discord.com/invite/dBfFAcefs2)
- [Maton Support](mailto:support@maton.ai)