# Instantly.ai Lead Pusher — Sync Leads to Campaigns (`ryanclinton/instantly-lead-pusher`) Actor

Pushes enriched leads into Instantly.ai campaigns via batch API. ICP score filtering, personalization templates, deduplication, dry-run preview, and Apify dataset chaining. $0.05 per lead processed.

- **URL**: https://apify.com/ryanclinton/instantly-lead-pusher.md
- **Developed by:** [ryan clinton](https://apify.com/ryanclinton) (community)
- **Categories:** Other
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, NaN bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per usage

This Actor is paid per platform usage. The Actor is free to use, and you only pay for the Apify platform usage, which gets cheaper the higher subscription plan you have.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-usage

## What's an Apify Actor?

Actors are a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp.md).

If your project is in a different language, use the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).


# README

## Instantly Lead Pusher

**Push enriched leads directly into Instantly.ai campaigns** without writing a single line of code. This actor takes scored, enriched leads from any Apify dataset — or inline JSON — and loads them into your Instantly campaign via the v1 batch API. It is built for sales teams and agencies that use Instantly for cold email and want to automate the gap between lead generation and campaign launch.

Every lead is mapped to Instantly's native fields: first name, last name, company name, phone, website, and personalization. ICP scores and grades travel alongside as custom variables, so your email sequences can reference `{{icpScore}}` and `{{icpGrade}}` directly. Dry-run mode (on by default) lets you preview the exact payload before a single contact is added to your campaign.

### What data can you extract?

The actor does not scrape — it pushes. The output dataset records every lead's processing result so you have a full audit trail.

| Data Point | Source | Example |
|---|---|---|
| 📧 **Email address** | Lead input | `sarah.chen@pinnacle-ind.com` |
| 👤 **First name** | Lead input / contacts array | `Sarah` |
| 👤 **Last name** | Lead input / contacts array | `Chen` |
| 🏢 **Company name** | Lead input | `Pinnacle Industries` |
| 📞 **Phone number** | Lead input / phones array | `+1-415-555-0192` |
| 🔗 **Website** | Lead input / domain field | `pinnacle-ind.com` |
| ⭐ **ICP score** | icpScore / score field | `87` |
| 🏅 **ICP grade** | icpGrade / grade field | `A` |
| 💬 **Rendered personalization** | Template + lead data | `Hi Sarah, I noticed Pinnacle Industries scored A on our ICP analysis.` |
| 📦 **Full Instantly payload** | Mapped output | `{ email, first_name, custom_variables... }` |
| ✅ **Push status** | Actor output | `pushed` / `dry_run` / `skipped` / `error` |
| ❌ **Skip reason** | Actor output | `ICP score 41 is below minimum 60.` |

### Why use Instantly Lead Pusher?

Manually exporting a CSV from one tool and importing it into Instantly takes 10-20 minutes per batch. You have to clean column headers, match field names, handle duplicates, and remember to set custom variables by hand. For agencies running multiple clients, this becomes a daily chore that blocks outreach from starting.

This actor automates the entire pipeline endpoint. Connect it downstream from [B2B Lead Gen Suite](https://apify.com/ryanclinton/b2b-lead-gen-suite), [B2B Lead Qualifier](https://apify.com/ryanclinton/b2b-lead-qualifier), or [Waterfall Contact Enrichment](https://apify.com/ryanclinton/waterfall-contact-enrichment), point it at your campaign ID, and leads flow in automatically — filtered, mapped, and personalized.

- **Scheduling** — run daily or weekly via Apify's built-in scheduler to keep campaigns topped up with fresh leads
- **API access** — trigger runs from Python, JavaScript, or any HTTP client to integrate with your existing stack
- **Dataset chaining** — pull directly from any Apify dataset by ID, so upstream actors hand off seamlessly
- **Monitoring** — get Slack or email alerts when runs fail or produce unexpected results
- **Integrations** — connect to Zapier, Make, or webhooks to trigger downstream actions when leads are pushed

### Features

- **Batch push up to 500 leads per API call** — the actor automatically splits large lists into 500-lead chunks and waits 500ms between batches to stay within Instantly's rate limits
- **Automatic API key validation** — before pushing any data, the actor calls `GET /campaign/list` to verify your key is valid, preventing silent failures
- **Personalization template rendering** — supports `{{variable}}` placeholders matched against any lead field; unknown variables are replaced with an empty string rather than left as literal text
- **ICP score filtering** — set a minimum ICP score (0-100) and the actor skips any lead below the threshold, recording the exact skip reason in the output
- **ICP custom variables** — `icpScore` and `icpGrade` are mapped to Instantly's `custom_variables` field automatically, making them available as merge tags in your email sequences
- **Legacy score field support** — accepts both `icpScore`/`icpGrade` (Lead Scoring Engine output) and `score`/`grade` (B2B Lead Qualifier output) without configuration
- **Flexible email extraction** — checks `lead.email`, then `contacts[].email`, then `emails[]` in priority order; leads with no resolvable email are skipped and logged
- **Full name splitting** — if only a full name string is available in `contacts[].name`, the actor splits it into first and last name using whitespace tokenization
- **Domain normalization** — strips `http://`, `https://`, and `www.` from website fields before sending to Instantly
- **Workspace and campaign deduplication** — `skipIfInWorkspace` and `skipIfInCampaign` flags delegate duplicate-checking to Instantly's own API, preventing double-outreach
- **Dry-run mode (default on)** — preview every mapped Instantly payload in the output dataset without touching your campaign; disable only when you are ready to commit
- **Per-lead PPE billing** — you are charged `$0.05` per lead successfully processed (pushed or previewed in dry-run), never for skipped leads
- **Spending limit enforcement** — the actor stops charging and halts when your configured budget ceiling is reached, so runs cannot overrun your cost cap
- **Inline or dataset input** — provide leads as a JSON array in the input, or pass an Apify dataset ID to chain with upstream actors

### Use cases for pushing leads to Instantly

#### Sales development representative (SDR) workflow automation

SDRs using Instantly for cold outreach often receive scored lead lists from a data team or RevOps. Instead of pasting CSVs into Instantly manually, they pipe the dataset ID into this actor and let it handle field mapping and deduplication. The ICP score lands as a custom variable, so sequence steps can reference it — "I saw your company scored {{icpScore}}/100 on our fit model" — without any additional CRM work.

#### Marketing agency campaign delivery

Agencies managing cold email for multiple clients run lead enrichment pipelines that produce scored, contact-enriched datasets. This actor sits at the end of each pipeline, pushing qualified leads into the correct client campaign. Scheduling the actor on a weekly cadence keeps each campaign populated with fresh prospects without requiring manual CSV exports.

#### Outbound pipeline with ICP gating

Growth teams that generate large volumes of raw leads use `minIcpScore` to gate what actually reaches Instantly. Combine [B2B Lead Qualifier](https://apify.com/ryanclinton/b2b-lead-qualifier) to score leads against your ICP criteria, then set `minIcpScore: 70` here to ensure only genuinely qualified contacts enter your sequences. Leads that fall below the threshold are recorded in the output with their exact score, so nothing is lost.

#### Event-driven lead loading after enrichment

Teams using [Waterfall Contact Enrichment](https://apify.com/ryanclinton/waterfall-contact-enrichment) to append emails to company lists can chain that actor's output dataset directly into this actor. A webhook from the enrichment run triggers the pusher, loading contacts into Instantly within minutes of enrichment completing — no human in the loop.

#### Dry-run field mapping audit before campaign launch

Before committing 500 contacts to a live campaign, use dry-run mode to verify that personalization templates render correctly, ICP scores are mapped, and no leads are missing emails. The output dataset shows the exact payload that would be sent to Instantly for each contact, so you can spot mapping issues before they affect a campaign.

#### Recruiting and talent sourcing outreach

Recruiters building outreach campaigns for passive candidates can load enriched candidate profiles with job title, company, and contact data directly into Instantly sequences. The personalization template can reference `{{title}}` and `{{companyName}}` from the lead record for context-aware messaging.

### How to push leads to Instantly

1. **Get your Instantly API key** — in Instantly, go to Settings > API and copy your key. Find your campaign ID in the campaign URL or via the Instantly API.
2. **Provide your leads** — paste them as a JSON array in the `leads` field, or enter an Apify dataset ID in `datasetId` if you are chaining from another actor. Each lead needs at minimum an `email` field.
3. **Configure your personalization template** — enter a template string like `Hi {{firstName}}, I noticed {{companyName}} scored {{icpGrade}} on our ICP analysis.` Leave blank to skip personalization.
4. **Run in dry-run first** — with `dryRun: true` (the default), click Start and check the Dataset tab. Review the `instantlyPayload` field for each lead to confirm fields mapped correctly. Then re-run with `dryRun: false` to push live.

### Input parameters

| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| `instantlyApiKey` | string | No | — | Your Instantly.ai API key. Leave empty to use dry-run mode without authentication. |
| `campaignId` | string | No | — | The Instantly campaign ID to add leads to. Found in the campaign URL. Required for live pushes. |
| `leads` | array | No | — | Lead records as a JSON array. Each object needs at least an `email` field. Mutually exclusive with `datasetId`. |
| `datasetId` | string | No | — | Apify dataset ID to pull leads from. Use to chain with B2B Lead Gen Suite, Lead Qualifier, or Waterfall Enrichment. |
| `personalizationTemplate` | string | No | — | Template for the Instantly personalization field. Use `{{fieldName}}` placeholders — e.g. `{{firstName}}`, `{{companyName}}`, `{{icpGrade}}`. |
| `minIcpScore` | integer | No | `0` | Filter leads with an ICP score below this value (0-100). Set to `0` to include all leads. |
| `skipIfInWorkspace` | boolean | No | `true` | Skip leads whose email already exists anywhere in your Instantly workspace. |
| `skipIfInCampaign` | boolean | No | `true` | Skip leads already present in the target campaign. |
| `dryRun` | boolean | No | `true` | Preview mapped Instantly fields without pushing to the campaign. Disable when ready to commit. |

#### Input examples

**Minimal live push — single lead:**
```json
{
    "instantlyApiKey": "YOUR_INSTANTLY_API_KEY",
    "campaignId": "cmp_abc123def456",
    "leads": [
        {
            "email": "james.okafor@betaindustries.com",
            "firstName": "James",
            "lastName": "Okafor",
            "companyName": "Beta Industries",
            "phone": "+44-20-7946-0812",
            "website": "betaindustries.com",
            "icpScore": 91,
            "icpGrade": "A"
        }
    ],
    "personalizationTemplate": "Hi {{firstName}}, I noticed {{companyName}} scored {{icpGrade}} on our ICP analysis — wanted to reach out.",
    "dryRun": false
}
````

**Dataset chaining — scored leads from upstream actor:**

```json
{
    "instantlyApiKey": "YOUR_INSTANTLY_API_KEY",
    "campaignId": "cmp_abc123def456",
    "datasetId": "ABC123xyzDatasetID",
    "personalizationTemplate": "Hi {{firstName}}, {{companyName}} looks like a strong fit for our {{industry}} clients.",
    "minIcpScore": 65,
    "skipIfInWorkspace": true,
    "skipIfInCampaign": true,
    "dryRun": false
}
```

**Dry-run preview — verify field mapping before committing:**

```json
{
    "leads": [
        {
            "email": "priya.sharma@novalogics.io",
            "firstName": "Priya",
            "lastName": "Sharma",
            "companyName": "Novalogics",
            "icpScore": 78,
            "icpGrade": "B",
            "industry": "SaaS"
        }
    ],
    "personalizationTemplate": "Hi {{firstName}}, I saw {{companyName}} is a {{industry}} company — thought this might be relevant.",
    "dryRun": true
}
```

#### Input tips

- **Always dry-run first** — verify that personalization renders correctly and all required fields are present before pushing to a live campaign.
- **Use `datasetId` for pipeline chaining** — if you ran B2B Lead Gen Suite or Waterfall Contact Enrichment, copy the output dataset ID directly into `datasetId` instead of exporting and re-importing.
- **Set `minIcpScore` to gate quality** — a threshold of 60-70 is a reasonable starting point for most B2B outreach campaigns; adjust based on your pipeline volume.
- **Leave `skipIfInWorkspace: true`** — this delegates deduplication to Instantly and prevents contacts from receiving outreach from multiple campaigns simultaneously.
- **Custom variables auto-populate** — any lead field not in the standard mapped set (email, name, company, phone, website, ICP fields) is automatically included as a `custom_variables` string, making it available as a merge tag in Instantly sequences.

### Output example

```json
{
    "email": "james.okafor@betaindustries.com",
    "firstName": "James",
    "lastName": "Okafor",
    "companyName": "Beta Industries",
    "status": "pushed",
    "dryRun": false,
    "icpScore": 91,
    "icpGrade": "A",
    "personalization": "Hi James, I noticed Beta Industries scored A on our ICP analysis — wanted to reach out.",
    "instantlyPayload": {
        "email": "james.okafor@betaindustries.com",
        "first_name": "James",
        "last_name": "Okafor",
        "company_name": "Beta Industries",
        "phone": "+44-20-7946-0812",
        "website": "betaindustries.com",
        "personalization": "Hi James, I noticed Beta Industries scored A on our ICP analysis — wanted to reach out.",
        "custom_variables": {
            "icpScore": "91",
            "icpGrade": "A"
        }
    },
    "skipReason": null,
    "error": null,
    "extractedAt": "2025-03-22T09:14:33.241Z"
}
```

The final record in each run is a summary:

```json
{
    "type": "summary",
    "totalLeads": 150,
    "pushed": 138,
    "skipped": 12,
    "errors": 0,
    "dryRun": false,
    "campaignId": "cmp_abc123def456",
    "batchCount": 1,
    "extractedAt": "2025-03-22T09:14:45.001Z"
}
```

### Output fields

| Field | Type | Description |
|---|---|---|
| `email` | string | Lead email address. |
| `firstName` | string | null | Lead first name extracted from the input. |
| `lastName` | string | null | Lead last name extracted from the input. |
| `companyName` | string | null | Lead company name. |
| `status` | string | `pushed`, `dry_run`, `skipped`, or `error`. |
| `dryRun` | boolean | Whether this record was produced in dry-run mode. |
| `icpScore` | number | null | ICP score (0-100) carried from the input lead. |
| `icpGrade` | string | null | ICP grade letter (A, B, C, D, F) carried from the input. |
| `personalization` | string | null | Rendered personalization string sent to Instantly. |
| `instantlyPayload` | object | null | Full payload as sent (or would be sent) to the Instantly API. |
| `instantlyPayload.email` | string | Email field in Instantly format. |
| `instantlyPayload.first_name` | string | First name in Instantly format. |
| `instantlyPayload.last_name` | string | Last name in Instantly format. |
| `instantlyPayload.company_name` | string | Company name in Instantly format. |
| `instantlyPayload.phone` | string | Phone number in Instantly format. |
| `instantlyPayload.website` | string | Normalized domain (no protocol, no www). |
| `instantlyPayload.personalization` | string | Rendered personalization string. |
| `instantlyPayload.custom_variables` | object | String-valued map of ICP fields and any extra lead fields. |
| `skipReason` | string | null | Explanation if the lead was skipped (e.g., low score, no email). |
| `error` | string | null | API error message if the push failed. |
| `extractedAt` | string | ISO 8601 timestamp of when the lead was processed. |
| `type` (summary) | `"summary"` | Present only on the final summary record. |
| `totalLeads` (summary) | number | Total leads in the input. |
| `pushed` (summary) | number | Leads successfully added to Instantly. |
| `skipped` (summary) | number | Leads skipped (no email, low score, or deduplication). |
| `errors` (summary) | number | Leads that failed due to API errors. |
| `batchCount` (summary) | number | Number of 500-lead API batches sent. |

### How much does it cost to push leads to Instantly?

Instantly Lead Pusher uses **pay-per-event pricing** — you pay **$0.05 per lead processed** (pushed or previewed in dry-run). Platform compute costs are included. Skipped leads (no email, below score threshold, or deduplicated by Instantly) are not charged.

| Scenario | Leads processed | Cost per lead | Total cost |
|---|---|---|---|
| Quick test | 10 | $0.05 | $0.50 |
| Small campaign | 100 | $0.05 | $5.00 |
| Mid-size campaign | 500 | $0.05 | $25.00 |
| Large campaign | 1,000 | $0.05 | $50.00 |
| Agency batch | 5,000 | $0.05 | $250.00 |

You can set a **maximum spending limit** per run to control costs. The actor stops charging when your budget is reached and records remaining leads as uncharged in the output.

Compare this to manual CSV import workflows that cost hours of team time per campaign — at $0.05/lead, loading 500 contacts into a campaign costs $25 and takes under two minutes.

### Push leads to Instantly using the API

#### Python

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_API_TOKEN")

run = client.actor("ryanclinton/instantly-lead-pusher").call(run_input={
    "instantlyApiKey": "YOUR_INSTANTLY_API_KEY",
    "campaignId": "cmp_abc123def456",
    "datasetId": "ABC123xyzDatasetID",
    "personalizationTemplate": "Hi {{firstName}}, I noticed {{companyName}} scored {{icpGrade}} on our ICP analysis.",
    "minIcpScore": 60,
    "skipIfInWorkspace": True,
    "skipIfInCampaign": True,
    "dryRun": False,
})

for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    if item.get("type") == "summary":
        print(f"Summary: {item['pushed']} pushed, {item['skipped']} skipped, {item['errors']} errors")
    else:
        print(f"{item['email']} → {item['status']} (ICP: {item.get('icpScore')})")
```

#### JavaScript

```javascript
import { ApifyClient } from "apify-client";

const client = new ApifyClient({ token: "YOUR_API_TOKEN" });

const run = await client.actor("ryanclinton/instantly-lead-pusher").call({
    instantlyApiKey: "YOUR_INSTANTLY_API_KEY",
    campaignId: "cmp_abc123def456",
    datasetId: "ABC123xyzDatasetID",
    personalizationTemplate: "Hi {{firstName}}, I noticed {{companyName}} scored {{icpGrade}} on our ICP analysis.",
    minIcpScore: 60,
    skipIfInWorkspace: true,
    skipIfInCampaign: true,
    dryRun: false,
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();
for (const item of items) {
    if (item.type === "summary") {
        console.log(`Summary: ${item.pushed} pushed, ${item.skipped} skipped, ${item.errors} errors`);
    } else {
        console.log(`${item.email} → ${item.status} | ICP: ${item.icpScore} | personalization: ${item.personalization}`);
    }
}
```

#### cURL

```bash
## Start the actor run
curl -X POST "https://api.apify.com/v2/acts/ryanclinton~instantly-lead-pusher/runs?token=YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "instantlyApiKey": "YOUR_INSTANTLY_API_KEY",
    "campaignId": "cmp_abc123def456",
    "datasetId": "ABC123xyzDatasetID",
    "personalizationTemplate": "Hi {{firstName}}, {{companyName}} scored {{icpGrade}} on our ICP model.",
    "minIcpScore": 60,
    "skipIfInWorkspace": true,
    "skipIfInCampaign": true,
    "dryRun": false
  }'

## Fetch results once the run completes (replace DATASET_ID from the run response)
curl "https://api.apify.com/v2/datasets/DATASET_ID/items?token=YOUR_API_TOKEN&format=json"
```

### How Instantly Lead Pusher works

#### Phase 1 — lead loading

The actor accepts leads from two sources: an inline JSON array provided directly in the `leads` field, or an Apify dataset loaded via the Apify client using the `datasetId` parameter. Dataset loads fetch up to 1,000 records per run. If neither source is provided, the actor halts immediately with an informative error rather than running silently.

#### Phase 2 — filtering and field mapping

Each lead passes through two filter gates before mapping. The first gate checks for a usable email address using a three-level lookup: `lead.email` is checked first, then `lead.contacts[].email` (iterating in order), then `lead.emails[]`. Leads with no resolvable email are counted and skipped. The second gate applies the `minIcpScore` threshold — if set above 0, leads with a known ICP score below the minimum are skipped and recorded with the exact score that caused the rejection.

Leads that pass both gates are mapped by `mapToInstantly()` in `mapper.ts`. Name extraction checks `lead.firstName`/`lead.lastName` first, then falls back to splitting `contacts[0].name` on whitespace. The website field is normalized by stripping protocol and `www.` prefix via the `URL` constructor. The personalization template is rendered by `renderTemplate()` using a `{{variable}}` regex substitution against all lead fields — unknown variables resolve to empty strings. Custom variables are assembled by `buildCustomVariables()`, which always includes `icpScore` and `icpGrade` (or their legacy equivalents `score`/`grade`), then appends any non-standard scalar lead fields as string-coerced key-value pairs.

#### Phase 3 — batch API push

In live mode, the actor first calls `GET /api/v1/campaign/list` with the API key to validate credentials before touching any lead data. Mapped payloads are then split into chunks of exactly 500 and sent sequentially to `POST /api/v1/lead/add` with the campaign ID, deduplication flags, and the lead array. The client waits 500ms between batches. A 30-second `AbortController` timeout is applied per request. On HTTP 429 responses, the client retries once after a 2-second delay before treating the batch as failed.

Instantly's API does not return per-lead success or failure within a batch — it returns aggregate `leads_added` and `leads_skipped` counts. If a batch request fails entirely, all leads in that batch are marked `error` in the output by walking through the result list in order and assigning batch-level errors to the corresponding position-indexed records.

#### Phase 4 — PPE billing and output

PPE charges are applied individually per lead, not per batch. In dry-run mode, a charge of `$0.05` is issued for each lead with `status: dry_run`. In live mode, charges are issued for each lead with `status: pushed`. If the spending limit is reached mid-run, the actor logs a warning, stops charging, and continues writing output records to the dataset without further charges. A summary record with `type: "summary"` is appended as the final dataset item.

### Tips for best results

1. **Dry-run before every new campaign.** Inspect the `instantlyPayload` field in the output to confirm field names, personalization rendering, and custom variable values before committing to a live campaign.
2. **Verify your campaign ID in the Instantly UI.** The campaign ID is visible in the URL when you open a campaign: `app.instantly.ai/app/campaign/YOUR_CAMPAIGN_ID`. Using the wrong ID will push leads into the wrong sequence.
3. **Keep `skipIfInWorkspace: true` unless you need re-engagement.** This prevents contacts from receiving simultaneous outreach across multiple campaigns and avoids the reputation damage of duplicate sends.
4. **Use ICP score gating to protect deliverability.** Sending to unqualified leads increases bounce and unsubscribe rates. A `minIcpScore` of 60-70 is a reasonable floor for most B2B outreach.
5. **Chain with B2B Lead Gen Suite for a complete pipeline.** Run [B2B Lead Gen Suite](https://apify.com/ryanclinton/b2b-lead-gen-suite) to generate and score leads, then pass the output dataset ID directly into this actor to push qualified contacts into Instantly in one automated workflow.
6. **Custom variables carry any lead field.** Any flat scalar field in your lead data beyond the standard mapped set (e.g., `employeeCount`, `fundingStage`, `techStack`) will automatically appear as a `custom_variables` entry in the Instantly payload, making it available as a merge tag in sequences.
7. **Set a spending limit for large batches.** If you are processing a large dataset and want to cap spend at a fixed amount, set a maximum cost per run in Apify's run settings. The actor will stop charging and halt cleanly when the limit is reached.
8. **Apify's free tier includes $5 of monthly credits** — enough to test with 100 leads at no cost before committing to larger runs.

### Combine with other Apify actors

| Actor | How to combine |
|---|---|
| [B2B Lead Gen Suite](https://apify.com/ryanclinton/b2b-lead-gen-suite) | Run the full pipeline — domain list to scored, enriched leads — then pass the output `datasetId` directly into Instantly Lead Pusher to load qualified contacts into your campaign. |
| [B2B Lead Qualifier](https://apify.com/ryanclinton/b2b-lead-qualifier) | Score raw lead lists against your ICP criteria (0-100), then use `minIcpScore` here to gate which contacts enter Instantly. |
| [Waterfall Contact Enrichment](https://apify.com/ryanclinton/waterfall-contact-enrichment) | Enrich company lists with emails via a 10-step waterfall, then push the enriched dataset directly into Instantly without exporting a CSV. |
| [Google Maps Lead Enricher](https://apify.com/ryanclinton/google-maps-lead-enricher) | Extract local business contacts from Google Maps, enrich them, and push the output dataset to Instantly for local outreach campaigns. |
| [Website Contact Scraper](https://apify.com/ryanclinton/website-contact-scraper) | Scrape emails and contacts from a list of business websites, then push the results into Instantly for outbound sequences. |
| [Email Pattern Finder](https://apify.com/ryanclinton/email-pattern-finder) | Detect company email naming conventions, generate addresses from a contact list, then load them into Instantly via this actor. |
| [Bulk Email Verifier](https://apify.com/ryanclinton/bulk-email-verifier) | Verify email deliverability before pushing to Instantly to reduce bounce rates and protect sender reputation. |

### Limitations

- **Instantly v1 API only** — the actor targets `https://api.instantly.ai/api/v1/lead/add`. If Instantly deprecates v1 or changes endpoint paths, the actor will need updating.
- **No per-lead push confirmation** — Instantly's batch API returns aggregate counts (`leads_added`, `leads_skipped`), not per-lead success flags. If a batch partially fails, the actor cannot identify which specific leads were added and which were not.
- **1,000 lead limit per dataset load** — when using `datasetId`, the actor fetches at most 1,000 records. For larger datasets, split into multiple runs or use the inline `leads` array with pre-paginated data.
- **No campaign existence validation** — the actor validates your API key but does not check whether the target campaign ID exists or is active before pushing. An invalid campaign ID will cause batch errors rather than a pre-flight failure.
- **Flat custom variables only** — nested objects and arrays in lead fields are excluded from `custom_variables` (Instantly requires string values). Only flat scalar fields are passed through automatically.
- **No retry on individual batch failures** — if a batch request fails (e.g., due to a transient network error after the one 429 retry), those leads are marked as errors and not re-queued.
- **Rate limiting** — very large runs (many thousands of leads) may encounter Instantly API rate limits beyond the 429 retry logic. If this occurs, split the run into smaller batches.
- **Dry-run charges PPE** — leads previewed in dry-run mode are charged at the same rate as live pushes. This is intentional — the full mapping, filtering, and template rendering work is performed in both modes.

### Integrations

- [Zapier](https://apify.com/integrations/zapier) — trigger Instantly Lead Pusher automatically when a new scored lead dataset is ready in a connected tool
- [Make](https://apify.com/integrations/make) — build multi-step automation scenarios that enrich, score, and push leads to Instantly on a schedule
- [Google Sheets](https://apify.com/integrations/google-sheets) — export the push result dataset to a Google Sheet for campaign tracking and reporting
- [Apify API](https://docs.apify.com/api/v2) — trigger runs programmatically from your CRM, data warehouse, or internal tools using the REST API
- [Webhooks](https://docs.apify.com/platform/integrations/webhooks) — fire a webhook when a push run completes to notify Slack, update a dashboard, or trigger the next stage in a pipeline
- [LangChain / LlamaIndex](https://docs.apify.com/platform/integrations) — use Apify's LangChain integration to trigger lead pushes as part of an AI-driven prospecting or research workflow

### Troubleshooting

- **All leads show `status: dry_run` but I set `dryRun: false`** — the actor treats missing `instantlyApiKey` or missing `campaignId` as an implicit dry-run, regardless of the `dryRun` setting. Verify that both fields are populated in your input.

- **API key validation fails** — the actor validates credentials against `GET /api/v1/campaign/list`. This requires the API key to have read access to campaigns. Check in Instantly's Settings > API that the key is active and has not been revoked. Keys generated for specific scopes may not pass this check.

- **All leads are skipped with "No valid email address found"** — check the field names in your lead data. The actor looks for `email` (string), `contacts[].email`, and `emails[]` (array). If your data uses a different field name (e.g., `emailAddress`), preprocess the data to rename the field before passing it to this actor.

- **Personalization shows empty values for some variables** — the template renderer substitutes unknown variables with an empty string rather than leaving `{{variableName}}` in the output. Check the `instantlyPayload.personalization` field in a dry-run output to confirm which variables resolved. Variables must match lead field names exactly, including case.

- **Batch errors with HTTP 400 or 422** — this typically means the campaign ID is invalid or the campaign is paused/deleted. Verify the campaign ID in the Instantly dashboard and confirm the campaign is in an active state that accepts new leads.

### Responsible use

- This actor pushes lead data you provide — it does not scrape or collect personal data itself.
- Ensure you have a lawful basis for processing and contacting the leads you push into Instantly campaigns.
- Comply with CAN-SPAM, GDPR, CASL, and any applicable regulations governing commercial email outreach in the regions you are targeting.
- Respect Instantly's terms of service, including their acceptable use policy for cold email.
- Do not use this actor to push leads to harassing, deceptive, or unauthorized campaigns.
- For guidance on data handling in outbound sales, see [Apify's blog on web scraping legality](https://blog.apify.com/is-web-scraping-legal/).

### FAQ

**How do I push leads to Instantly without writing code?**
Open the actor on the Apify Store, enter your Instantly API key and campaign ID in the input form, paste your leads as a JSON array, and click Start. No code is required. Run with `dryRun: true` first to preview the output, then re-run with `dryRun: false` to push live.

**How many leads can I push to Instantly in one run?**
The actor supports up to 1,000 leads per run when loading from a dataset (limited by the dataset fetch), or any number when using the inline `leads` array. Leads are pushed in batches of 500 with a 500ms delay between batches, so 1,000 leads complete in under two minutes.

**Does pushing leads to Instantly deduplicate contacts automatically?**
Yes, with `skipIfInWorkspace: true` (the default), Instantly will reject any lead whose email already exists anywhere in your workspace. With `skipIfInCampaign: true`, leads already in the target campaign are also skipped. Both flags are on by default.

**What lead data format does this actor accept?**
Any JSON object with at minimum an `email` field. The actor also accepts output from [B2B Lead Gen Suite](https://apify.com/ryanclinton/b2b-lead-gen-suite), [B2B Lead Qualifier](https://apify.com/ryanclinton/b2b-lead-qualifier), [Waterfall Contact Enrichment](https://apify.com/ryanclinton/waterfall-contact-enrichment), [Google Maps Lead Enricher](https://apify.com/ryanclinton/google-maps-lead-enricher), and any other actor that produces lead-shaped records.

**How does the personalization template work?**
You write a template string with `{{fieldName}}` placeholders matching field names in your lead data. The actor replaces each placeholder with the corresponding lead field value. For example, `Hi {{firstName}}, I saw {{companyName}} scored {{icpGrade}}` becomes `Hi James, I saw Beta Industries scored A`. Unknown placeholders resolve to empty strings.

**Can I filter leads by ICP score before pushing to Instantly?**
Yes. Set `minIcpScore` to any value between 1 and 100. Leads with an ICP score below the threshold are skipped and recorded in the output with a skip reason. Leads without an ICP score field are not filtered (they pass through unless `minIcpScore` is above 0).

**Is it legal to push cold outreach leads into Instantly?**
Legality depends on your jurisdiction and how you collected the lead data. In the US, CAN-SPAM permits commercial email with valid opt-out mechanisms. In the EU, GDPR requires a lawful basis such as legitimate interest for B2B cold outreach. This actor is a delivery mechanism — compliance responsibility lies with how you collected and are using the lead data. See [Apify's web scraping legality guide](https://blog.apify.com/is-web-scraping-legal/) for background.

**How is this different from importing a CSV into Instantly manually?**
CSV import requires exporting from your data source, cleaning column headers to match Instantly's format, mapping custom fields by hand, checking for duplicates manually, and repeating the process every time you want to add fresh leads. This actor handles field mapping, deduplication, ICP filtering, and personalization rendering automatically. It can be scheduled and chained with upstream actors so leads flow into Instantly without human intervention.

**What happens if my Instantly API key is invalid?**
The actor validates the key before pushing any leads by calling the campaign list endpoint. If the key returns a 401 or 403, the actor halts immediately with an error message and pushes no leads. No PPE charges are incurred for a failed validation.

**Can I schedule this actor to run automatically?**
Yes. Use Apify's built-in scheduler to run this actor on a daily, weekly, or custom cron schedule. Set `datasetId` to the output of an upstream actor that refreshes on the same schedule, and your Instantly campaigns will be topped up with fresh, qualified leads automatically.

**How do ICP scores appear in Instantly email sequences?**
The actor maps `icpScore` and `icpGrade` to `custom_variables` in the Instantly payload. In your Instantly email template, reference them as `{{icpScore}}` and `{{icpGrade}}`. For example: "I noticed your company scored {{icpScore}}/100 on our fit analysis." These resolve to the numeric score and letter grade for each contact.

**What does dry-run mode actually do?**
Dry-run mode performs every step — loading leads, filtering by email and ICP score, mapping fields, rendering personalization templates — but skips the API call to Instantly. The output dataset shows the full `instantlyPayload` object for each lead exactly as it would be sent. PPE charges apply in dry-run mode at the same rate as live mode.

### Help us improve

If you encounter issues, you can help us debug faster by enabling run sharing in your Apify account:

1. Go to [Account Settings > Privacy](https://console.apify.com/account/privacy)
2. Enable **Share runs with public Actor creators**

This lets us see your run details when something goes wrong, so we can fix issues faster. Your data is only visible to the actor developer, not publicly.

### Support

Found a bug or have a feature request? Open an issue in the [Issues tab](https://console.apify.com/actors/ryanclinton~instantly-lead-pusher/issues) on this actor's page. For custom solutions or enterprise integrations, reach out through the Apify platform.

# Actor input Schema

## `instantlyApiKey` (type: `string`):

Your Instantly.ai API key. Found in Settings > API. Leave empty to use dry-run preview mode.

## `campaignId` (type: `string`):

The Instantly.ai campaign ID to add leads to. Found in the campaign URL or via the Instantly API.

## `leads` (type: `array`):

Lead data to push into Instantly. Each object needs at least an email. Supports output from B2B Lead Gen Suite, Lead Scoring Engine, or custom data.

## `datasetId` (type: `string`):

Apify dataset ID to pull leads from (alternative to inline leads). Use this to chain with Lead Scoring Engine or B2B Lead Gen Suite.

## `personalizationTemplate` (type: `string`):

Template for the Instantly personalization field. Use {{variable}} placeholders matching lead field names — e.g. {{companyName}}, {{icpGrade}}, {{firstName}}. Leave empty to skip.

## `minIcpScore` (type: `integer`):

Filter out leads with an ICP score below this threshold. Set to 0 to include all leads. Requires leads to have an icpScore field (from Lead Scoring Engine).

## `skipIfInWorkspace` (type: `boolean`):

If true, Instantly will skip leads whose email already exists anywhere in your workspace (across all campaigns). Avoids duplicate outreach.

## `skipIfInCampaign` (type: `boolean`):

If true, Instantly will skip leads already present in the target campaign. Prevents re-adding existing contacts.

## `dryRun` (type: `boolean`):

Preview the mapped Instantly fields without actually pushing to the campaign. Useful for verifying field mapping before committing.

## Actor input object example

```json
{
  "campaignId": "your-campaign-id-here",
  "leads": [
    {
      "email": "sarah.chen@acmecorp.com",
      "firstName": "Sarah",
      "lastName": "Chen",
      "companyName": "Acme Corp",
      "phone": "+1-415-555-0192",
      "website": "acmecorp.com",
      "icpScore": 82,
      "icpGrade": "A"
    }
  ],
  "personalizationTemplate": "Hi {{firstName}}, I noticed {{companyName}} scored {{icpGrade}} on our ICP analysis.",
  "minIcpScore": 0,
  "skipIfInWorkspace": true,
  "skipIfInCampaign": true,
  "dryRun": true
}
```

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "campaignId": "your-campaign-id-here",
    "leads": [
        {
            "email": "sarah.chen@acmecorp.com",
            "firstName": "Sarah",
            "lastName": "Chen",
            "companyName": "Acme Corp",
            "phone": "+1-415-555-0192",
            "website": "acmecorp.com",
            "icpScore": 82,
            "icpGrade": "A"
        }
    ],
    "personalizationTemplate": "Hi {{firstName}}, I noticed {{companyName}} scored {{icpGrade}} on our ICP analysis.",
    "minIcpScore": 0,
    "dryRun": true
};

// Run the Actor and wait for it to finish
const run = await client.actor("ryanclinton/instantly-lead-pusher").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "campaignId": "your-campaign-id-here",
    "leads": [{
            "email": "sarah.chen@acmecorp.com",
            "firstName": "Sarah",
            "lastName": "Chen",
            "companyName": "Acme Corp",
            "phone": "+1-415-555-0192",
            "website": "acmecorp.com",
            "icpScore": 82,
            "icpGrade": "A",
        }],
    "personalizationTemplate": "Hi {{firstName}}, I noticed {{companyName}} scored {{icpGrade}} on our ICP analysis.",
    "minIcpScore": 0,
    "dryRun": True,
}

# Run the Actor and wait for it to finish
run = client.actor("ryanclinton/instantly-lead-pusher").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "campaignId": "your-campaign-id-here",
  "leads": [
    {
      "email": "sarah.chen@acmecorp.com",
      "firstName": "Sarah",
      "lastName": "Chen",
      "companyName": "Acme Corp",
      "phone": "+1-415-555-0192",
      "website": "acmecorp.com",
      "icpScore": 82,
      "icpGrade": "A"
    }
  ],
  "personalizationTemplate": "Hi {{firstName}}, I noticed {{companyName}} scored {{icpGrade}} on our ICP analysis.",
  "minIcpScore": 0,
  "dryRun": true
}' |
apify call ryanclinton/instantly-lead-pusher --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=ryanclinton/instantly-lead-pusher",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Instantly.ai Lead Pusher — Sync Leads to Campaigns",
        "description": "Pushes enriched leads into Instantly.ai campaigns via batch API. ICP score filtering, personalization templates, deduplication, dry-run preview, and Apify dataset chaining. $0.05 per lead processed.",
        "version": "1.0",
        "x-build-id": "lIK7uTDolxaUL9gDd"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/ryanclinton~instantly-lead-pusher/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-ryanclinton-instantly-lead-pusher",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/ryanclinton~instantly-lead-pusher/runs": {
            "post": {
                "operationId": "runs-sync-ryanclinton-instantly-lead-pusher",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/ryanclinton~instantly-lead-pusher/run-sync": {
            "post": {
                "operationId": "run-sync-ryanclinton-instantly-lead-pusher",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "properties": {
                    "instantlyApiKey": {
                        "title": "Instantly API Key",
                        "type": "string",
                        "description": "Your Instantly.ai API key. Found in Settings > API. Leave empty to use dry-run preview mode."
                    },
                    "campaignId": {
                        "title": "Campaign ID",
                        "type": "string",
                        "description": "The Instantly.ai campaign ID to add leads to. Found in the campaign URL or via the Instantly API."
                    },
                    "leads": {
                        "title": "Leads (inline data)",
                        "type": "array",
                        "description": "Lead data to push into Instantly. Each object needs at least an email. Supports output from B2B Lead Gen Suite, Lead Scoring Engine, or custom data.",
                        "default": [
                            {
                                "email": "sarah.chen@acmecorp.com",
                                "firstName": "Sarah",
                                "lastName": "Chen",
                                "companyName": "Acme Corp",
                                "phone": "+1-415-555-0192",
                                "website": "acmecorp.com",
                                "icpScore": 82,
                                "icpGrade": "A"
                            }
                        ]
                    },
                    "datasetId": {
                        "title": "Apify Dataset ID",
                        "type": "string",
                        "description": "Apify dataset ID to pull leads from (alternative to inline leads). Use this to chain with Lead Scoring Engine or B2B Lead Gen Suite."
                    },
                    "personalizationTemplate": {
                        "title": "Personalization Template",
                        "type": "string",
                        "description": "Template for the Instantly personalization field. Use {{variable}} placeholders matching lead field names — e.g. {{companyName}}, {{icpGrade}}, {{firstName}}. Leave empty to skip."
                    },
                    "minIcpScore": {
                        "title": "Minimum ICP Score",
                        "minimum": 0,
                        "maximum": 100,
                        "type": "integer",
                        "description": "Filter out leads with an ICP score below this threshold. Set to 0 to include all leads. Requires leads to have an icpScore field (from Lead Scoring Engine).",
                        "default": 0
                    },
                    "skipIfInWorkspace": {
                        "title": "Skip if already in workspace",
                        "type": "boolean",
                        "description": "If true, Instantly will skip leads whose email already exists anywhere in your workspace (across all campaigns). Avoids duplicate outreach.",
                        "default": true
                    },
                    "skipIfInCampaign": {
                        "title": "Skip if already in this campaign",
                        "type": "boolean",
                        "description": "If true, Instantly will skip leads already present in the target campaign. Prevents re-adding existing contacts.",
                        "default": true
                    },
                    "dryRun": {
                        "title": "Dry run (preview only)",
                        "type": "boolean",
                        "description": "Preview the mapped Instantly fields without actually pushing to the campaign. Useful for verifying field mapping before committing.",
                        "default": true
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
