Email tools

Instantly API Guide: Keys, Rate Limits, Leads and Campaigns

Instantly API v2: key and scopes, the 100 req/s rate limit, adding leads, creating and launching campaigns, sending accounts and webhooks, with curl examples.

Max Korolev
Max KorolevFounder & CEO, Outreach2dayPublished 8 min read
On this page

Short answer: the Instantly API v2 lives at https://api.instantly.ai/api/v2. You authenticate with an API key in an Authorization: Bearer header; each key has scopes such as leads:create. Every Instantly plan includes API access (Growth $47, Hypergrowth $97, Light Speed $358 a month); webhooks start at Hypergrowth. The limit is 100 requests a second and 6,000 a minute for the whole workspace. API v1 was deprecated on January 19, 2026.

This guide covers the calls most cold email teams need: add sending accounts, turn on warmup, create a campaign, add leads, launch, read analytics and receive webhooks. Every endpoint, field and limit below comes from Instantly's own developer docs, read on 15 October 2026 and linked in each section. For the AI-assistant side of the same API, see Instantly MCP: setup, tools and limits.

Instantly API at a Glance

Instantly API v2

Source

Base URL

https://api.instantly.ai/api/v2/...

API reference

Auth

Authorization: Bearer <key>

Authorization

Scopes

Per key, resource:action, e.g. leads:create, campaigns:update, all:all

Create lead

Rate limit

100 requests a second and 6,000 a minute per workspace, shared by v1, v2 and every key; 429 above it

Rate limit

Pagination

limit and starting_after; responses return items and next_starting_after

List leads

Plans

API on Growth, Hypergrowth and Light Speed; webhooks from Hypergrowth

Pricing

Errors

JSON with statusCode, error, message; 402 when the workspace has no active paid plan

Create lead

Spec

OpenAPI 3.1 at https://api.instantly.ai/openapi/api_v2.json

llms.txt

v1

Deprecated on January 19, 2026; v2 keys are separate from v1 keys

v1 migration

Get an API Key

  1. Open Settings, Integrations in Instantly (app.instantly.ai/app/settings/integrations) and pick API Keys in the left sidebar.

  2. Click Create API Key, name it and select the scopes. A script that only adds leads needs leads:create; a full setup script needs campaign and account scopes too.

  3. Copy the key. Instantly shows it once and cannot show it again (getting started).

Keep it in an environment variable and test it with a small read:

export INSTANTLY_API_KEY="your_key"

curl "https://api.instantly.ai/api/v2/campaigns?limit=10" \
  -H "Authorization: Bearer $INSTANTLY_API_KEY"

A missing or wrong key answers 401. A key without the scope the endpoint needs is refused too, so give each script its own key with the smallest set of scopes.

Rate Limits and Pagination

Instantly counts requests per workspace: no more than 100 a second and 6,000 a minute, across v1, v2 and every key you created. Above either limit the request fails with 429. Instantly's own advice for large jobs is to send batches of 100 calls with a 2-second pause between batches (rate limit).

Two things keep the request count low. Use the bulk endpoints (up to 1,000 leads in one call), and page with a cursor: pass limit and the next_starting_after value from the previous page as starting_after.

Add Sending Accounts

POST /api/v2/accounts adds one sending account. The required fields are email, first_name, last_name, provider_code and the IMAP and SMTP username, password, host and port (create account). provider_code tells Instantly what the account is, and Instantly warns that a wrong code leaves the account unusable:

provider_code

Account type

1

Custom IMAP/SMTP

2

Google

3

Microsoft

4

AWS

8

AirMail

11

Airmail Instant

For an SMTP/IMAP mailbox, such as one from Outreach2day, the call looks like this (host and ports are the ones every Outreach2day mailbox uses):

curl -X POST "https://api.instantly.ai/api/v2/accounts" \
  -H "Authorization: Bearer $INSTANTLY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "email": "anna@acmemail.com",
    "first_name": "Anna",
    "last_name": "Lee",
    "provider_code": 1,
    "imap_username": "anna@acmemail.com",
    "imap_password": "MAILBOX_PASSWORD",
    "imap_host": "outreachmailstream.com",
    "imap_port": 993,
    "smtp_username": "anna@acmemail.com",
    "smtp_password": "MAILBOX_PASSWORD",
    "smtp_host": "outreachmailstream.com",
    "smtp_port": 465
  }'

Google and Microsoft accounts connect through a separate OAuth flow that Instantly documents in its OAuth connection guide.

Turn On Warmup

POST /api/v2/accounts/warmup/enable takes up to 100 addresses in emails, or include_all_emails with up to 100 excluded_emails. It starts a background job; poll GET /api/v2/background-jobs/{id} for the result (enable warmup). POST /api/v2/accounts/warmup/disable turns it off.

curl -X POST "https://api.instantly.ai/api/v2/accounts/warmup/enable" \
  -H "Authorization: Bearer $INSTANTLY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"emails": ["anna@acmemail.com", "ben@acmemail.com"]}'

Mailboxes exported from Outreach2day already warm up in Outreach2day, and that warmup keeps running after the export, so Instantly's warmup is optional for them.

Create a Campaign

POST /api/v2/campaigns needs name and campaign_schedule. The schedule needs at least one entry in schedules, each with name, timing (from and to as HH:MM), days (boolean keys "0" to "6"; the reference does not say which number is Monday, so check the schedule in the app after the first call) and a timezone from Instantly's list (create campaign).

The email copy goes in sequences. It is an array, but Instantly reads only the first element, so put every step into sequences[0].steps. Each step needs type ("email"), delay (in days unless delay_unit says minutes or hours) and at least one variant with subject and body. email_list picks the sending accounts. A campaign with two steps, built from those fields:

curl -X POST "https://api.instantly.ai/api/v2/campaigns" \
  -H "Authorization: Bearer $INSTANTLY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Q4 SaaS founders",
    "campaign_schedule": {
      "schedules": [{
        "name": "Main schedule",
        "timing": {"from": "09:00", "to": "17:00"},
        "days": {"1": true, "2": true, "3": true,
                 "4": true, "5": true},
        "timezone": "America/Chicago"
      }]
    },
    "sequences": [{
      "steps": [
        {"type": "email", "delay": 3, "variants": [{
          "subject": "Quick question",
          "body": "Hi there,<br/><br/>..."
        }]},
        {"type": "email", "delay": 4, "variants": [{
          "subject": "",
          "body": "Following up on my note.<br/>..."
        }]}
      ]
    }],
    "email_list": ["anna@acmemail.com", "ben@acmemail.com"],
    "daily_limit": 50,
    "stop_on_reply": true
  }'

The response returns the campaign with its id. Start it with POST /api/v2/campaigns/{id}/activate and stop it with POST /api/v2/campaigns/{id}/pause (activate).

Add Leads

POST /api/v2/leads/add adds up to 1,000 leads in one request, to a campaign (campaign_id) or to a list (list_id); a call takes one of the two. With campaign_id every lead needs an email. skip_if_in_workspace, skip_if_in_campaign and skip_if_in_list drop duplicates, and verify_leads_on_import checks the addresses on the way in (add leads in bulk).

curl -X POST "https://api.instantly.ai/api/v2/leads/add" \
  -H "Authorization: Bearer $INSTANTLY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "campaign_id": "CAMPAIGN_ID",
    "skip_if_in_workspace": true,
    "leads": [
      {"email": "john@example.com", "first_name": "John",
       "company_name": "Example Inc.",
       "custom_variables": {"industry": "SaaS"}}
    ]
  }'

For a single lead, POST /api/v2/leads takes the same fields with campaign for the campaign id (create lead). POST /api/v2/leads/list searches leads; it is a POST because the filters are complex.

The same upload in Python, in chunks of 1,000 with a pause on 429:

import os, time, requests

KEY = os.environ["INSTANTLY_API_KEY"]
URL = "https://api.instantly.ai/api/v2/leads/add"

def add_leads(campaign_id, leads):
    for i in range(0, len(leads), 1000):
        body = {"campaign_id": campaign_id,
                "skip_if_in_workspace": True,
                "leads": leads[i:i + 1000]}
        while True:
            r = requests.post(URL, json=body, timeout=60,
                headers={"Authorization": f"Bearer {KEY}"})
            if r.status_code != 429:
                break
            time.sleep(2)
        r.raise_for_status()

Read Analytics

GET /api/v2/campaigns/analytics returns campaign analytics; pass id for one campaign or leave it out for all, and narrow the dates with start_date and end_date (campaign analytics). There are overview, daily and per-step variants as well.

curl "https://api.instantly.ai/api/v2/campaigns/analytics?id=CAMPAIGN_ID&start_date=2026-10-01" \
  -H "Authorization: Bearer $INSTANTLY_API_KEY"

Free guide19 min read

Send 100,000 cold emails a month

Domains and mailboxes you need, DNS, warmup, lists, copy and follow-ups, with a launch checklist, sent to your inbox.

Unsubscribe in one click.

Webhooks

POST /api/v2/webhooks needs only target_hook_url; event_type picks one event or all_events, and campaign limits it to one campaign (create webhook). Events include email_sent, email_opened, email_link_clicked, reply_received, email_bounced, lead_unsubscribed, campaign_completed, account_error and the lead status events such as lead_interested and lead_meeting_booked. GET /api/v2/webhooks/event-types lists them. Webhooks need the Hypergrowth plan or above.

curl -X POST "https://api.instantly.ai/api/v2/webhooks" \
  -H "Authorization: Bearer $INSTANTLY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"target_hook_url": "https://example.com/hooks/instantly",
       "event_type": "reply_received"}'

Each payload carries timestamp, event_type, workspace, campaign_id and campaign_name, plus lead and email fields where they apply. Instantly's webhook guide spells the click event link_clicked while the API list says email_link_clicked; match on the value you receive (webhook events).

Connect Outreach2day Mailboxes With the API Key

You do not need to call POST /api/v2/accounts for mailboxes you buy from Outreach2day. Paste your Instantly API key once in the Outreach2day app (Export to sequencer) and export the mailboxes in one click: Outreach2day creates each one in Instantly as a custom IMAP/SMTP account (provider code 1) with its logins, adds new mailboxes as they are created and, with auto reconnect on, reconnects ones that drop. The field-by-field setup inside Instantly is on the Instantly integration page, and the same export through our REST API is in add email accounts to Instantly or Smartlead via API.

Outreach2day mailboxes cost $2.50 a month each (12 minimum), with warmup and a sending engine included, set up in about 12 minutes on your own domains. Teams that want one product can also send from Outreach2day's own campaigns; for 1,000 mailboxes and more, the volume price is set on a call. Other routes in: the cold email API for domains, mailboxes and warmup, and the Smartlead API guide if you send from Smartlead.

Instantly API From an AI Assistant

Instantly's MCP server at https://mcp.instantly.ai/mcp turns the same V2 API into tools for Claude, Cursor and other MCP clients, with the same key. Setup per client, the tool list and its limits are on Instantly MCP: setup, tools and limits.

FAQ

Is the Instantly API free?

There is no separate API fee. Instantly's pricing page lists API access on every plan from Growth at $47 a month; webhooks need Hypergrowth ($97) or above.

What is the Instantly API rate limit?

100 requests a second and 6,000 a minute, for the whole workspace and shared by every key and by API v1 and v2. Requests over the limit get 429.

Can I still use Instantly API v1?

Instantly deprecated v1 on January 19, 2026, and v1 keys do not work with v2. Its migration guide says Zapier and Make integrations built on v1 keep working.

How many leads can I add in one request?

Up to 1,000 with POST /api/v2/leads/add, into one campaign or one list.

How do I add many sending accounts at once?

The API adds one account per POST /api/v2/accounts call. For mailboxes from Outreach2day, the export with your Instantly API key adds them all in one click and keeps new ones in sync.

Get Started

Create an Outreach2day account, order mailboxes on your domains and connect Instantly with its API key; the mailboxes arrive in Instantly warm.

Free guide

Send 100,000 cold emails a month

How to send 100,000 cold emails a month while keeping quality, engagement and conversion rates high: domains, mailboxes, warmup, leads, copy and scaling

Step-by-step playbook · 19 min read
  • Agent skill

    Cold email lead list cleaner

Deliverability call

Talk to our deliverability team

Book a call with the people who run our mailbox infrastructure. We look at your current setup and tell you what to change.

  • Review your domains, DNS records and current inbox placement
  • Size the setup: domains, mailboxes per domain and daily volume per mailbox
  • Plan warmup and the move from your current provider or sequencer

Free call

See open times in your time zone and book on this page.

Or open the booking page