All Posts

Instantly Webhooks and API: Build Custom Integrations

Instantly handles your cold email sending, warmup, and campaign management. But the moment you need lead status changes to update your CRM, enrichment data to flow into campaigns automatically, or reply events to trigger downstream workflows, you're working with the Instantly API and webhooks.

Instantly Webhooks and API: Build Custom Integrations

Published on
February 26, 2026

Overview

Instantly handles your cold email sending, warmup, and campaign management. But the moment you need lead status changes to update your CRM, enrichment data to flow into campaigns automatically, or reply events to trigger downstream workflows, you're working with the Instantly API and webhooks. And the gap between "I set up a webhook" and "I have a reliable, production-grade integration" is where most GTM teams lose hours to debugging silent failures.

This guide is for GTM engineers who want to build custom integrations with Instantly's API and webhook system. We'll cover authentication, the webhook event types you'll actually use, payload structures, common integration patterns for CRM sync and lead routing, and the error handling strategies that keep your pipelines running when things go wrong. If you've already read our overview of Instantly integrations and want to go deeper on the technical implementation, this is the next step.

We won't spend time on Zapier or Make middleware here. This is about direct API calls and webhook handlers: the approach that gives you the most control, the lowest latency, and the fewest dependencies on third-party automation platforms.

Instantly API Authentication

Instantly uses API key authentication, which is the simplest model you'll encounter in the GTM stack. No OAuth flows, no token refresh logic, no consent screens. You generate a key, pass it with every request, and you're in.

Generating and Managing API Keys

Navigate to Settings, then Integrations, then API in your Instantly dashboard to generate a key. Each key is scoped to your workspace and has full access to the API endpoints available on your plan.

Key Management Basics

Treat your Instantly API key like a password. Store it in environment variables or a secrets manager, never in source code, Clay formulas, or shared documents. If a key leaks, rotate it immediately from the dashboard. Unlike OAuth tokens, API keys don't expire on their own, so a compromised key stays valid until you manually revoke it.

Instantly's API key is passed as a query parameter (api_key) or in the request body depending on the endpoint. This is worth noting because it differs from the more common Authorization: Bearer header pattern used by tools like HubSpot and Salesforce. If you're building a generic HTTP client wrapper for your GTM stack, you'll need to handle this variation. For a broader look at authentication patterns across the GTM stack, our REST API authentication guide covers the seven methods you'll encounter.

API Base URL and Versioning

Instantly's API lives at https://api.instantly.ai/api/v1/ for the v1 endpoints and https://api.instantly.ai/api/v2/ for the newer v2 endpoints. The v2 API covers more functionality and follows more consistent conventions, but some operations still require v1 calls. Check the endpoint documentation for each operation you need, and be prepared to use both versions in the same integration.

Rate Limits

Instantly enforces rate limits on API calls, though the exact thresholds depend on your plan tier. The general pattern is a per-second and per-minute cap. When you hit the limit, you'll receive a 429 Too Many Requests response with a Retry-After header indicating when you can resume.

For teams running high-volume lead pushes or polling for campaign analytics, rate limits become a real constraint. Implement exponential backoff with jitter from the start rather than retrofitting it after your first production outage. Batch endpoints where available (like bulk lead creation) reduce your call count significantly compared to creating leads one at a time.

OperationEndpoint (v2)MethodRate Limit Sensitivity
Add leads to campaign/leadsPOSTHigh (batch to reduce calls)
Get lead status/leadsGETMedium (use webhooks instead of polling)
List campaigns/campaignsGETLow
Get campaign analytics/campaigns/analyticsGETMedium
Update lead status/leads/statusPUTHigh (batch when possible)
Delete leads/leadsDELETEMedium

Webhook Event Types and Payloads

Webhooks are how Instantly tells your systems that something happened. Instead of polling the API every 30 seconds to check for new replies (which burns rate limit budget and introduces latency), you register a URL and Instantly pushes event data to you in near real-time.

Available Event Types

Instantly fires webhooks for the events that matter most in cold email operations. Here are the ones you'll build around:

Event TypeWhen It FiresPrimary Use Case
reply_receivedA lead replies to any email in a sequenceRoute to CRM, trigger rep notification, classify sentiment
email_openedA lead opens an email (pixel-tracked)Engagement scoring, warm lead identification
link_clickedA lead clicks a tracked linkIntent scoring, content engagement tracking
email_bouncedEmail delivery fails (hard or soft bounce)Data hygiene, list cleanup, sender reputation protection
lead_unsubscribedLead clicks unsubscribe linkCompliance, suppression list management, CRM status update
sequence_completedLead reaches end of email sequenceMove to nurture, update CRM stage, trigger next workflow
lead_status_changedLead status updated in InstantlyCRM sync, pipeline reporting, workflow branching

Payload Structure

Each webhook delivers a JSON payload containing the event metadata and the relevant lead and campaign data. A typical reply webhook payload looks something like this:

Example: reply_received Payload

event_type: The event identifier (e.g., reply_received)
timestamp: ISO 8601 timestamp of when the event occurred
lead_email: The lead's email address
campaign_id: Which campaign triggered the event
campaign_name: Human-readable campaign name
account_email: The sending account that received the reply
email_subject: Subject line of the email thread
reply_text: The body of the lead's reply
step: Which step in the sequence triggered the reply
custom_variables: Any custom fields you passed when creating the lead

The inclusion of custom_variables in webhook payloads is important. If you pushed enrichment data from Clay into Instantly as custom fields (company size, industry, ICP score), those fields come back in the webhook. This means your webhook handler has context about who replied without making an additional API call to look up the lead. This follows the "fat payload" pattern that keeps your integrations fast and resilient.

Configuring Webhooks

You set up webhooks in Instantly's dashboard under Settings, then Webhooks. For each webhook, you specify the target URL (your endpoint), the event types to listen for, and optionally filter by campaign. You can also configure webhooks programmatically via the API, which is useful for teams managing multiple workspaces or automating environment setup.

1
Deploy your webhook endpoint first. Have your handler running and returning 200 responses before you register the webhook in Instantly. If your endpoint isn't ready when Instantly tries to verify it, the webhook creation will fail.
2
Start with reply_received. This is the highest-value event for most teams. Get reply handling production-ready before adding open tracking, bounce handling, and other events.
3
Filter by campaign during testing. Point your webhook at a test campaign first. Once your handler is reliable, expand to all campaigns. This prevents a buggy handler from dropping real production events.
4
Log raw payloads from the start. Store every incoming webhook payload in a database or logging service before processing. When something breaks (and it will), you'll need these raw payloads to debug and replay.

Common Integration Patterns

Knowing the API endpoints and webhook events is table stakes. The real work is building integration patterns that solve specific GTM problems. Here are the patterns that come up most frequently.

Pattern 1: Enrichment-to-Campaign Pipeline

The most common Instantly API use case: automatically pushing enriched leads from your research pipeline into campaigns. Instead of exporting CSVs from Clay and manually importing them, you call the Instantly API to create leads programmatically.

The flow looks like this: Clay (or your enrichment tool of choice) finishes enriching a lead. Your workflow calls the Instantly POST /leads endpoint with the lead's email, name, company, and all the custom variables your email templates reference. The lead is immediately added to the target campaign and begins receiving emails on the next send window.

Key implementation details that trip teams up:

  • Campaign ID mapping. You need to know which campaign to add the lead to. Hard-coding campaign IDs works for simple setups, but if you're routing leads to different campaigns based on persona, ICP tier, or industry, you need a mapping layer. Pull campaign IDs via the GET /campaigns endpoint and build a lookup table that your enrichment workflow references.
  • Custom variable naming. The variable names you pass via the API must exactly match the merge tags in your email templates. A mismatch means blank fields in sent emails. Standardize your variable naming convention across Clay, Instantly, and your CRM from the start. Our guide on field mapping across CRM, sequencer, and analytics covers this in detail.
  • Deduplication. If a lead already exists in the campaign, the API's behavior depends on your configuration. Test this explicitly. You don't want to reset a lead's sequence position by accidentally re-adding them. The principles from avoiding duplicate sends when merging Clay and CRM apply directly here.

Pattern 2: Reply-to-CRM Routing

When a lead replies to a cold email, that event needs to reach your CRM within seconds, not hours. The reply_received webhook drives this pattern.

Your webhook handler receives the reply event, extracts the lead email and reply content, then calls your CRM API to either update an existing contact record or create a new one. The specific CRM actions typically include:

  • Creating a task for the account owner to follow up
  • Updating the contact's lifecycle stage or lead status
  • Logging the reply as an activity or note on the contact record
  • Triggering a Slack notification to the assigned rep

The challenge is matching the lead email from Instantly to the correct contact in your CRM. Email address is the obvious match key, but you'll encounter edge cases: leads who reply from a different email address, shared inboxes, and email aliases. Build your matching logic to handle these gracefully rather than silently dropping events. For CRM-specific implementation guidance, see our articles on HubSpot field mapping and Salesforce field mapping.

Pattern 3: Engagement-Based Lead Scoring

Open and click webhooks feed your lead scoring model with real-time engagement data. Instead of batch-syncing engagement metrics daily, each event incrementally updates the lead's score.

A practical scoring model for cold email engagement might look like:

EventScore ImpactNotes
Email opened (first)+2First open only; subsequent opens are noise
Link clicked+5Indicates active interest, especially pricing/demo links
Reply (positive)+15Requires sentiment classification to distinguish from "unsubscribe"
Reply (negative/unsubscribe)-10Should also trigger sequence removal
Email bounced-20Invalidates the contact; flag for data cleanup
Sequence completed (no engagement)-5Lead went through full sequence with zero interaction

The critical implementation detail is deduplication. Instantly may fire multiple open events for the same email view (image proxy reloads, email client prefetching). Your scoring logic should track which events it has already processed and ignore duplicates. For a broader framework on turning these signals into action, see how to turn buying signals into trigger-based outreach.

Pattern 4: Bounce-Driven Data Hygiene

Bounces are a data quality signal, not just a deliverability problem. When the email_bounced webhook fires, your handler should:

  1. Update the lead's email validity status in your CRM
  2. Remove the lead from all active Instantly campaigns via the API
  3. Flag the lead in your enrichment tool for re-verification
  4. If bounce rate for a specific data source exceeds a threshold, alert your team to investigate the source quality

Hard bounces versus soft bounces require different handling. A hard bounce (invalid address) means the data is bad and the lead should be permanently suppressed. A soft bounce (full inbox, temporary server issue) might resolve on its own. Instantly distinguishes between these in the webhook payload, so build your logic accordingly.

Lead Status Sync Between Instantly and CRM

Lead status sync is where most Instantly integrations get complicated. The challenge isn't moving data; it's deciding which system is the source of truth for which fields and handling the inevitable conflicts.

Defining Ownership Rules

Before writing any code, establish clear ownership. A workable default:

Data TypeSource of TruthSync Direction
Email engagement (opens, clicks, replies)InstantlyInstantly to CRM
Lead status (interested, meeting booked, etc.)Both (with conflict rules)Bidirectional
Account/opportunity dataCRMCRM to Instantly
Contact info (email, title, company)CRM or enrichment toolOne-way to Instantly
Sequence membershipInstantlyInstantly to CRM
Suppression/do-not-contactCRMCRM to Instantly

Bidirectional Status Sync

The trickiest field is lead status, because both systems have legitimate reasons to update it. A rep marks a lead as "Meeting Booked" in the CRM. Instantly needs to know so it stops the sequence. Conversely, when Instantly detects an unsubscribe, the CRM needs to know so reps don't call someone who asked to be removed.

The implementation requires two components:

  1. Instantly to CRM: Your lead_status_changed webhook handler maps Instantly statuses to CRM lifecycle stages and updates the contact record. Include a custom field on the CRM record (something like last_updated_by_source) that records which system made the change.
  2. CRM to Instantly: A CRM webhook (HubSpot workflow or Salesforce trigger) fires when relevant fields change. Your handler calls the Instantly API to update the lead status or remove them from campaigns.

The last_updated_by_source field is critical for preventing infinite loops. When your Instantly webhook handler updates the CRM, it sets the source to "instantly." Your CRM webhook handler checks this field before syncing back to Instantly. If the change came from Instantly, skip the reverse sync.

Watch Out for Sync Loops

Without the source tracking field, a status change in Instantly updates the CRM, which triggers the CRM webhook, which updates Instantly, which triggers the Instantly webhook, which updates the CRM... indefinitely. This is the most common failure mode in bidirectional sync. Build the loop prevention logic before you enable bidirectional sync, not after you discover the loop in production. For deeper guidance on managing sync between tools, see Clay data to CRM sync.

Status Mapping

Instantly's lead statuses don't map one-to-one with CRM lifecycle stages. You need a translation layer. Here's a starting point:

Instantly StatusHubSpot Lifecycle StageSalesforce Lead Status
InterestedSales Qualified LeadWorking - Contacted
Meeting BookedOpportunityWorking - Meeting Set
Meeting CompletedOpportunityWorking - Qualified
Not InterestedOther (with lost reason)Closed - Not Interested
Out of OfficeNo changeNo change (retry later)
Wrong PersonUnqualifiedClosed - Disqualified

Customize this mapping to your sales process. The important thing is documenting it explicitly so everyone on the team knows how statuses translate between systems.

Error Handling and Reliability

Your Instantly integration will fail. The API will return 500 errors during maintenance windows. Your webhook endpoint will go down for a deployment. A network blip will drop a payload. The question isn't whether failures happen, but whether your integration recovers gracefully or loses data silently.

Webhook Handler Architecture

The single most important reliability pattern: decouple webhook ingestion from processing. Your webhook endpoint should accept the payload, write it to a queue or database, return a 200 response, and do nothing else. All the actual work (CRM updates, scoring calculations, Slack notifications) happens asynchronously from a separate worker process.

1
Receive and acknowledge. Accept the POST request, validate the payload structure (check for required fields like event_type and lead_email), write the raw payload to your event store, and return HTTP 200 within 5 seconds. If your endpoint takes longer than 10 seconds to respond, Instantly may consider the delivery failed and retry.
2
Queue for processing. A worker process reads events from your queue (SQS, Redis, Pub/Sub, or even a database table acting as a queue). For each event, the worker executes the business logic: CRM updates, score calculations, notifications.
3
Retry on failure. If the CRM API is down, your worker catches the error and puts the event back in the queue with a retry delay. Use exponential backoff: 1 second, 2 seconds, 4 seconds, up to a cap of 5 minutes.
4
Dead letter after exhaustion. After 5-10 failed retry attempts, move the event to a dead letter queue (DLQ). Alert your team via Slack or PagerDuty. These events need manual investigation, not infinite retries.

This pattern is covered in more depth in our webhook best practices guide, but the core principle applies to every Instantly integration: never let a downstream failure cause you to drop an incoming event.

Idempotent Processing

Instantly may send the same webhook event more than once. Network timeouts, retries, and infrastructure hiccups all cause duplicate deliveries. Your processing logic must handle duplicates gracefully.

The implementation is straightforward: maintain a set of processed event identifiers. Before processing any event, check if you've already handled it. If so, skip it. Use a combination of event type, lead email, campaign ID, and timestamp to construct a unique identifier if Instantly doesn't provide an explicit event ID in the payload.

Idempotency in Practice

For CRM updates, use upsert operations rather than create-or-update logic. An upsert that sets a contact's status to "Interested" is inherently idempotent: running it twice produces the same result. A create operation that adds a new activity record every time is not idempotent and will produce duplicates. Design your downstream operations to be safe to repeat.

API Error Handling

When calling the Instantly API (as opposed to receiving webhooks), implement error handling for these common scenarios:

HTTP StatusMeaningHandling Strategy
400 Bad RequestInvalid payload (missing required fields, bad format)Log the error with full payload, do not retry (fix the data first)
401 UnauthorizedInvalid or revoked API keyAlert immediately. Likely needs key rotation. Do not retry.
404 Not FoundCampaign or lead doesn't existVerify IDs, may indicate a campaign was deleted. Log and skip.
429 Too Many RequestsRate limit exceededRespect Retry-After header. Implement exponential backoff.
500 Internal Server ErrorInstantly-side issueRetry with backoff. If persistent, check Instantly status page.
503 Service UnavailableMaintenance or overloadRetry with backoff. Queue pending operations.

Monitoring and Alerting

Your integration is only as reliable as your ability to detect when it breaks. At minimum, monitor:

  • Webhook ingestion rate: If you normally receive 50 events per hour and suddenly receive zero, something is wrong. Alert on unexpected drops.
  • Processing lag: Time between event ingestion and completed processing. If this grows, your worker can't keep up with volume.
  • Error rate: Percentage of events that fail processing. Anything above 5% over a 15-minute window deserves investigation.
  • Dead letter queue depth: Any events hitting the DLQ should trigger an alert. These represent real data that didn't make it to your CRM or scoring system.
  • API call success rate: Track the success rate of your outbound calls to Instantly's API. A sudden spike in 429s or 500s indicates either a volume problem or an Instantly-side issue.

Build a simple dashboard that shows these metrics in real time. When a sales leader asks "why didn't this lead get followed up?" you need to trace the event's journey from Instantly webhook to CRM update in minutes, not hours.

Advanced Integration Patterns

Once the basics are solid, these patterns extract more value from Instantly's API.

AI-Powered Reply Classification

The reply_received webhook gives you the reply text. Instead of routing every reply to a human for triage, pass the reply through an LLM to classify intent before routing. Categories might include: interested (wants to learn more), meeting request (ready to schedule), objection (has concerns), not interested (clear rejection), out of office (auto-reply), and wrong person (not the decision maker).

This classification drives different downstream actions automatically. Meeting requests go straight to your scheduling tool. Objections get routed with suggested rebuttals. Not-interested leads get removed from campaigns. Out-of-office replies get paused and retried later. The manual triage step disappears for 70-80% of replies, which matters significantly when you're generating hundreds of replies per week across personalized campaigns at scale.

Dynamic Campaign Routing

Instead of pushing all enriched leads to a single campaign, use enrichment data to route leads to the most relevant campaign automatically. Your API integration layer checks the lead's industry, company size, persona, or ICP tier and maps them to the appropriate campaign ID.

This enables segment-specific messaging without manual list management. When your enrichment pipeline identifies a lead as a VP of Engineering at a Series B fintech company, the API call routes them to the campaign with messaging tailored to that exact persona. The routing logic lives in your integration layer, not in Instantly, giving you full control over the rules. Teams building sophisticated Clay research to qualification to sequence pipelines use this pattern to automate the last-mile connection between enrichment and execution.

Sequence Branching Based on CRM Data

Use CRM webhooks to modify a lead's journey in Instantly based on deal stage changes. If a lead gets added to an opportunity in your CRM, your CRM webhook handler calls the Instantly API to remove them from outbound sequences. If a closed-lost deal reopens, you might re-enroll the contact in a re-engagement campaign.

This pattern requires the bidirectional sync infrastructure described in the lead status sync section, plus CRM webhook handlers that translate deal-level events into Instantly API actions. It's more complex to implement but prevents the embarrassing scenario where a prospect who just signed a contract keeps receiving cold emails.

What Changes at Scale

Building a custom Instantly integration for one campaign sending to 500 leads is manageable. You write a webhook handler, connect it to your CRM, and everything works. But GTM teams don't stay at that volume. When you're running 20 campaigns across three personas, syncing to a CRM with 50,000 contacts, and processing 2,000 webhook events per day, the integration architecture that worked at small scale starts to crack.

The first thing that breaks is context. Your reply classification needs enrichment data that lives in Clay. Your lead routing needs ICP scores that were computed during qualification. Your CRM updates need to reflect not just the Instantly event but the full history of that contact across every tool in your stack. Each of these requirements means another API call, another data lookup, another potential failure point in your webhook processing pipeline.

The second thing that breaks is maintenance. Every custom integration is code you wrote, which means it's code you maintain. When Instantly ships a new API version, you update your integration. When your CRM schema changes, you update field mappings. When you add a new campaign type, you extend your routing logic. Multiply this across every tool-to-tool connection in your stack and the maintenance burden becomes a full-time job.

What you actually need is a unified context layer that sits between all your GTM tools and handles the orchestration, normalization, and context assembly that your custom integrations are doing piecemeal. Instead of building point-to-point connections from Instantly to your CRM, from Clay to Instantly, from your CRM back to Instantly, you connect each tool once to a central system that maintains the full picture.

This is what platforms like Octave are built for. Octave maintains a unified context graph across your GTM stack, so when an Instantly webhook fires, the processing layer already has the lead's enrichment data, ICP score, CRM history, and engagement timeline. You don't need to make four API calls to assemble context for a single reply event. And when your stack changes, you update one connection instead of rebuilding every point-to-point integration. For teams running serious outbound volume, it's the difference between spending your time building GTM logic and spending it maintaining data plumbing.

FAQ

Does Instantly support webhook signature verification?

Instantly's webhook implementation is simpler than platforms like HubSpot or Stripe when it comes to payload signing. If signature verification isn't available for your webhook configuration, implement compensating controls: restrict your endpoint to known IP ranges, validate payload schema strictly, and verify that referenced campaign IDs and lead emails actually exist in your Instantly workspace before processing. See our REST API authentication guide for alternative security strategies.

How do I handle webhook events when my endpoint is down for deployment?

Instantly retries failed webhook deliveries, so short downtime windows (a few minutes) usually resolve themselves. For longer maintenance, consider deploying a lightweight proxy endpoint (on a serverless platform like AWS Lambda or Cloudflare Workers) that accepts and queues all incoming webhooks. Your main handler processes from the queue when it comes back online. Zero-downtime deployments using blue-green or rolling strategies eliminate this problem entirely.

Should I use Instantly's v1 or v2 API?

Use v2 wherever it covers the functionality you need. The v2 API has more consistent endpoint naming, better error responses, and expanded coverage. However, some operations are still v1-only, so check the documentation for each specific endpoint. It's common for production integrations to use both versions simultaneously.

How do I test webhook integrations without sending real cold emails?

Create a test campaign in Instantly with a small list of email addresses you control (team members' secondary addresses work well). Send a short sequence and trigger real replies, bounces, and opens against your staging webhook endpoint. You can also capture production webhook payloads (with sensitive data redacted), store them, and replay them against your staging environment for regression testing.

What's the latency between an event occurring and the webhook firing?

For most events, webhooks fire within seconds. Reply detection depends on email sync frequency, so there may be a slight delay (typically under a minute) between when the reply arrives in the sending account's inbox and when Instantly processes and fires the webhook. Open tracking events fire nearly instantly since they're triggered by pixel loads. Plan your SLAs accordingly: near-real-time, not instant.

Can I use Instantly's API to manage sending accounts and warmup?

Yes, the API supports account management operations including adding sending accounts, configuring warmup settings, and monitoring account health. This is particularly useful for agencies managing many client workspaces or teams that programmatically spin up new sending infrastructure. Check the v2 API documentation for the full list of account management endpoints.

Conclusion

Instantly's API and webhook system give GTM engineers the building blocks for tight, real-time integrations between cold email execution and the rest of the stack. The core patterns, enrichment-to-campaign pipelines, reply-to-CRM routing, engagement-based scoring, and bidirectional status sync, cover the majority of what teams need to eliminate manual handoffs and data silos in their outbound operations.

The implementation details matter more than the architecture diagrams. Idempotent processing prevents duplicate CRM records. Source tracking fields prevent sync loops. Dead letter queues prevent silent data loss. Exponential backoff prevents cascading failures during API hiccups. Get these patterns right and your integration runs itself. Skip them and you'll spend your Mondays debugging why 200 leads didn't get routed over the weekend.

Start with the reply webhook and CRM sync. That single integration delivers immediate value by getting hot leads in front of reps faster. Once that's reliable, layer on engagement scoring, bounce handling, and dynamic campaign routing. Each pattern builds on the same infrastructure, so the incremental effort drops with each addition. The goal is an outbound system where data flows automatically between tools, every event triggers the right action, and your team focuses on strategy rather than data plumbing.

FAQ

Frequently Asked Questions

Still have questions? Get connected to our support team.