Explee Public API
Version: 1.0.0
> Tip: This documentation is designed for humans. To integrate with AI agents, provide them with the OpenAPI schema at https://api.explee.com/public/api/openapi.json instead.
Search millions of companies worldwide using natural language queries and structured filters!
Rate limit: 10000 requests per hour, 150 concurrent requests per organization. Timeout: 90s.
Authentication
ApiKeyAuth: apiKey - Get your API key at [API Keys](https://explee.com/api-keys)
Endpoints
POST /public/api/v1/search/companies
Companies
Search for companies using structured definitions.
## How It Works
Provide a structured definition of your target companies in the `definition` field — our AI will find matching companies.
All other filters are optional.
See the request schema below for the full list of available filters.
**Definition examples:**
- `"YouTube video summarization tool"`
- `"electronic signature platform"`
- `"AI B2B SaaS"`
- `"real estate company"`
## AI Enrichment
Use the `criteria` parameter to score companies against custom criteria.
Each company will be evaluated and scored (0-5) with reasoning for each criterion.
## Pricing
- **First 100 results are free** (including AI enrichment)
- **0.5 credits** per company after the first 100
- **+0.1 credits** per company per criterion after the first 100
Example: 150 companies with 2 criteria = 50 billable × (0.5 + 0.1 × 2) = 35 credits (first 100 are free)
Empty results = 0 credits.
## Deduplication
Pass dedup list ids in `exclude_lists` to skip companies you already own — they are not returned
and not charged. Free results zone does not apply. See the Deduplication endpoints.
Request Body
Request body required
Responses
200: Successful Response401: Invalid or missing API key. Include `X-API-Key` header.402: Insufficient credit balance. Top up your account.422: Validation error. Check request body and parameters.429: Rate limit exceeded (10000/hour) or concurrent limit reached (150 per organization).500: Internal server error. Contact support if persists.504: Request timeout. Please try again later.
POST /public/api/v1/search/companies-by-domains
Companies by Domains
Find companies by their domains.
**How it works:**
1. Provide a list of company domains (up to 1000)
2. The system looks up each domain and returns **at most one** company profile per domain (the best match by quality score)
**Pricing:**
- **0.5 credit(s)** per company found
- **0 credits** for domains not found
**Limits:**
- Maximum 1000 domains per request
- Maximum 10000 companies per response
**Deduplication:**
- Pass dedup list ids in `exclude_lists` — matched companies are not returned and not charged
Request Body
Request body required
Responses
200: Successful Response401: Invalid or missing API key. Include `X-API-Key` header.402: Insufficient credit balance. Top up your account.422: Validation error. Check request body and parameters.429: Rate limit exceeded (10000/hour) or concurrent limit reached (150 per organization).500: Internal server error. Contact support if persists.504: Request timeout. Please try again later.
POST /public/api/v1/search/people
People
Search for people (employees) at companies matching your criteria.
## How It Works
Provide `job_titles` in `people_filters` to find people by their role.
Use `company_filters.definition` to narrow down which companies to search.
Use `company_linkedin_ids` to restrict results to a specific list of company LinkedIn IDs.
**Job title examples:**
- `["Head of Sales", "VP Sales"]`
- `["CTO", "VP Engineering"]`
- `["Founder", "CEO"]`
## AI Enrichment
Use the `criteria` parameter in `people_filters` to score people against custom criteria.
Each person will be evaluated and scored (0-5) with reasoning for each criterion.
## Pricing
- **First 100 results are free** (including AI enrichment)
- **1.0 credit** per person after the first 100
- **+0.1 credits** per person per criterion after the first 100
Example: 150 people with 2 criteria = 50 billable × (1.0 + 0.1 × 2) = 60 credits (first 100 are free)
Empty results = 0 credits.
## Deduplication
Pass dedup list ids in `exclude_lists` to skip people you already own — they are not returned
and not charged. Free results zone does not apply. See the Deduplication endpoints.
Request Body
Request body required
Responses
200: Successful Response401: Invalid or missing API key. Include `X-API-Key` header.402: Insufficient credit balance. Top up your account.422: Validation error. Check request body and parameters.429: Rate limit exceeded (10000/hour) or concurrent limit reached (150 per organization).500: Internal server error. Contact support if persists.504: Request timeout. Please try again later.
POST /public/api/v1/search/people-by-domains
People by Domains
Find people at companies by their domains.
**How it works:**
1. Provide a list of company domains (up to 1000) and job titles to search for
2. The system finds companies by domains
3. Returns up to `people_per_company` people per found company with matching job titles
**Job title matching:**
- Uses semantic search: "Head of Sales" will match "VP Sales", "Sales Director", etc.
- Multiple job titles are combined with OR logic
**Parameters:**
- `people_per_company`: Number of people to return per company (1-1000, default: 1)
**Limits:**
- Maximum 1000 domains per request
- Maximum 20 job titles per request
- Maximum 1000 people per company
- Maximum 10000 people per response (total)
**Billing:**
- 1 credit per person returned
**Deduplication:**
- Pass dedup list ids in `exclude_lists` — matched people are not returned and not charged
Request Body
Request body required
Responses
200: Successful Response401: Invalid or missing API key. Include `X-API-Key` header.402: Insufficient credit balance. Top up your account.422: Validation error. Check request body and parameters.429: Rate limit exceeded (10000/hour) or concurrent limit reached (150 per organization).500: Internal server error. Contact support if persists.504: Request timeout. Please try again later.
POST /public/api/v1/search/nl-to-filters
NL to Filters
Convert a free-form natural language query into structured filters for companies and people search.
## How It Works
Send any query in plain English (or another language), for example:
- `"SaaS companies using Stripe"`
- `"Founders of AI startups in Germany"`
- `"B2B fintech companies in US and Canada"`
The endpoint returns parsed filters in the same shape used by search endpoints:
- `companies_filters`
- `people_filters`
- `focus` (`companies` or `people`)
This endpoint does not perform a search and does not charge credits.
Request Body
Request body required
Responses
200: Successful Response401: Invalid or missing API key. Include `X-API-Key` header.402: Insufficient credit balance. Top up your account.422: Validation error. Check request body and parameters.429: Rate limit exceeded (10000/hour) or concurrent limit reached (150 per organization).500: Internal server error. Contact support if persists.504: Request timeout. Please try again later.
POST /public/api/v1/enrich/email
Find email by name
Find email address for a single person.
## How It Works
Provide the person's first name, last name, and company domain.
## Presets
| Preset | Cost | Success Rate | Description |
|--------|------|--------------|-------------|
| **basic** | 1.5 credits | ~50% | Single provider, pattern-based lookup. Fast and cheap. |
| **premium** | 5.0 credits | ~78% | 6 providers with cross-validation. Higher accuracy. |
## Pricing
You are only charged when an email is found.
Email not found = 0 credits.
Request Body
Request body required
Responses
200: Successful Response401: Invalid or missing API key. Include `X-API-Key` header.402: Insufficient credit balance. Top up your account.422: Validation error. Check request body and parameters.429: Rate limit exceeded (10000/hour) or concurrent limit reached (150 per organization).500: Internal server error. Contact support if persists.504: Request timeout. Please try again later.
POST /public/api/v1/enrich/phone
Find phone by LinkedIn URL
Find the work phone number for a single person.
## How It Works
Provide the person's LinkedIn profile URL (`linkedin_url`) and we'll find their work
phone. You can also pass a known `email` if you have one.
## Presets
| Preset | Cost | Success Rate | Description |
|--------|------|--------------|-------------|
| **basic_new** | 15.0 credits | ~45% | Faster, lower-cost lookup. |
| **premium** | 30.0 credits | ~60% | Broader, multi-source lookup. Higher hit rate. |
## Pricing
You are only charged when a phone is found.
Phone not found = 0 credits.
Request Body
Request body required
Responses
200: Successful Response401: Invalid or missing API key. Include `X-API-Key` header.402: Insufficient credit balance. Top up your account.422: Validation error. Check request body and parameters.429: Rate limit exceeded (10000/hour) or concurrent limit reached (150 per organization).500: Internal server error. Contact support if persists.504: Request timeout. Please try again later.
POST /public/api/v1/enrich/email/batch
Find email by name (batch request)
Find email addresses for multiple contacts in one request (async).
**How it works:**
1. Submit up to 100 contacts with first_name, last_name, company_domain
2. Receive a `task_id` immediately
3. Poll GET endpoint with `task_id` to check status and retrieve results
**Limits:**
- Maximum 100 contacts per batch
**Pricing:**
- **basic**: 1.5 credits per found email
- **premium**: 5 credits per found email
- Only charged for emails found (not found = 0 credits)
Request Body
Request body required
Responses
200: Successful Response401: Invalid or missing API key. Include `X-API-Key` header.402: Insufficient credit balance. Top up your account.422: Validation error. Check request body and parameters.429: Rate limit exceeded (10000/hour) or concurrent limit reached (150 per organization).500: Internal server error. Contact support if persists.504: Request timeout. Please try again later.
GET /public/api/v1/enrich/email/batch/{task_id}
Find email by name (batch results)
Check status and retrieve results for a batch request.
**Statuses (in meta.status):**
- `pending` — processing in progress, poll again in a few seconds
- `completed` — results ready, `contacts` array contains enriched data
- `failed` — error occurred, see `meta.error` for details
**Response structure:**
- `contacts` — null while pending, array when completed
- `meta.status` — current processing status
- `meta.error` — error description (null if no error)
- `meta.credits_charged` — credits used (only charged for found emails)
**Typical workflow:**
1. POST to submit batch, get `task_id`
2. GET with `task_id`, check `meta.status`
3. If `pending`, wait 2-5 seconds and poll again
4. When `completed`, read `contacts` array
Parameters
task_id (path, required): Task ID returned from POST request
Responses
200: Successful Response401: Invalid or missing API key. Include `X-API-Key` header.402: Insufficient credit balance. Top up your account.422: Validation error. Check request body and parameters.429: Rate limit exceeded (10000/hour) or concurrent limit reached (150 per organization).500: Internal server error. Contact support if persists.504: Request timeout. Please try again later.404: Batch not found
POST /public/api/v1/find-and-enrich
Find people and enrich their emails (async)
Search for people matching your filters and enrich their emails in a single async job.
**How it works:**
1. Submit search filters + `max_contacts` (how many contacts with emails you want, max 500 per call)
2. Receive a `task_id` immediately
3. Poll the GET endpoint with `task_id` for `progress` (with `eta_seconds`) and results
4. For more than `max_contacts`, call again with the previous response's `next_cursor`
**Pricing:**
- **Search is free** — you are never charged for people searched.
- **basic**: 1.5 credits per found email · **premium**: 5 credits per found email.
- You are charged ONLY for emails actually found. Worst-case credits are held up front (402 if insufficient).
**Deduplication:** pass `exclude_lists` to skip people you already own — they are not enriched and not charged.
Request Body
Request body required
Responses
200: Successful Response401: Invalid or missing API key. Include `X-API-Key` header.402: Insufficient credit balance. Top up your account.422: Validation error. Check request body and parameters.429: Rate limit exceeded (10000/hour) or concurrent limit reached (150 per organization).500: Internal server error. Contact support if persists.504: Request timeout. Please try again later.
GET /public/api/v1/find-and-enrich/{task_id}
Find-and-enrich job status and results
Check progress and retrieve results for a find-and-enrich job.
**Statuses (in meta.status):**
- `pending` — running; read `meta.progress` (incl. `eta_seconds`) and poll again
- `completed` — results ready; `contacts` holds the enriched contacts, `meta.next_cursor`/`meta.has_more` for paging
- `failed` — error occurred (or timed out — credits released), see `meta.error`
Only contacts with a found email are returned. `meta.credits_charged` reflects found emails only.
Parameters
task_id (path, required): Task ID returned from POST request
Responses
200: Successful Response401: Invalid or missing API key. Include `X-API-Key` header.402: Insufficient credit balance. Top up your account.422: Validation error. Check request body and parameters.429: Rate limit exceeded (10000/hour) or concurrent limit reached (150 per organization).500: Internal server error. Contact support if persists.504: Request timeout. Please try again later.404: Job not found
GET /public/api/v1/tasks
List async tasks
List all async tasks for your organization, including find-and-enrich jobs,
batch email enrichments, and campaign lead imports.
**Use cases:**
- Track async jobs across every API key owned by the same organization
- Find task IDs you may have lost
- Monitor pending vs completed tasks
**Response:**
- `tasks` — array of task objects with status and result URL
- `total` — total count for pagination
**Filtering:**
- Use `status` parameter to filter by task status (pending, completed, failed)
Parameters
status (query, optional): Filter by task statuslimit (query, optional): Maximum number of tasks to returnoffset (query, optional): Number of tasks to skip (for pagination)
Responses
200: Successful Response422: Validation Error
GET /public/api/v1/agents
List Explee agents
Returns all pre-built Explee agents. Each agent has a fixed system prompt, input/output schema, and search strategy. Use the agent `id` with the "Run Explee agent" endpoint.
Responses
200: Successful Response401: Invalid or missing API key. Include `X-API-Key` header.402: Insufficient credit balance. Top up your account.422: Validation error. Check request body and parameters.429: Rate limit exceeded (10000/hour) or concurrent limit reached (150 per organization).500: Internal server error. Contact support if persists.504: Request timeout. Please try again later.
POST /public/api/v1/agents/{agent_id}/runs
Run Explee agent
Run a pre-built Explee agent by its ID. Explee agents come with a tuned system prompt, search strategy, and output schema — you only provide the input data.
Use `GET /public/api/v1/agents` to browse available agents and their expected input schemas.
**Cost**: 1 credit per run.
Parameters
agent_id (path, required)
Request Body
Request body required
Responses
200: Successful Response401: Invalid or missing API key. Include `X-API-Key` header.402: Insufficient credit balance. Top up your account.422: Validation error. Check request body and parameters.429: Rate limit exceeded (10000/hour) or concurrent limit reached (150 per organization).500: Internal server error. Contact support if persists.504: Request timeout. Please try again later.404: Agent not found
POST /public/api/v1/agents/runs
Run custom agent
Run a fully custom agent — you provide the system prompt, input/output schemas, and input data.
Use this when Explee's pre-built agents don't fit your use case. The agent will execute asynchronously; poll `GET /agents/runs/{job_id}` for results.
**Cost**: 1 credit per run.
Request Body
Request body required
Responses
200: Successful Response401: Invalid or missing API key. Include `X-API-Key` header.402: Insufficient credit balance. Top up your account.422: Validation error. Check request body and parameters.429: Rate limit exceeded (10000/hour) or concurrent limit reached (150 per organization).500: Internal server error. Contact support if persists.504: Request timeout. Please try again later.
GET /public/api/v1/agents/runs/{run_id}
Get agent run status
Get the current status of an agent run.
Returns `input` (original input data), `result` (agent output on success), and `meta` (status, progress, timing).
Parameters
Responses
200: Successful Response401: Invalid or missing API key. Include `X-API-Key` header.402: Insufficient credit balance. Top up your account.422: Validation error. Check request body and parameters.429: Rate limit exceeded (10000/hour) or concurrent limit reached (150 per organization).500: Internal server error. Contact support if persists.504: Request timeout. Please try again later.
POST /public/api/v1/web/search
Web Search
Search the web using our internal search infrastructure.
Returns up to 10 organic search results (title, snippet, URL) for a given query.
If fewer results are available, returns as many as found.
## Pricing
- **Flat rate: 0.005 credits per request** ($0.05 per 1,000 requests)
## Rate Limit
- **400,000 requests per hour** per API key
Request Body
Request body required
Responses
200: Successful Response401: Invalid or missing API key. Include `X-API-Key` header.402: Insufficient credit balance. Top up your account.422: Validation error. Check request body and parameters.429: Rate limit exceeded (10000/hour) or concurrent limit reached (150 per organization).500: Internal server error. Contact support if persists.504: Request timeout. Please try again later.
POST /public/api/v1/billing/topup
Top up credits
> ⚠️ **Restricted access** — the billing API is enabled per organization. If you
> get a `403`, request access via [email protected].
Buy credits and charge your organization's saved card immediately.
Use this to refill programmatically when your balance runs low (poll
`GET /public/api/v1/billing/balance` to decide when). Credits are priced at
**1 credit = $0.01**, so `credits` is also the price in cents.
## Request body
| Field | Type | Required | Notes |
|-------|------|----------|-------|
| `credits` | integer | yes | How many credits to buy. **Minimum 500** ($5), **maximum 100000** ($1,000) per call. |
| `idempotency_key` | string | no (recommended) | Safe-retry token — see below. |
There is also a **rolling-24h limit of 1,000,000 credits ($10,000) per organization** across all top-up calls — a safety cap. Above it the call returns `429` (see below).
### idempotency_key — how to use it (important for automated callers)
If a request times out or errors and you're not sure it went through, **retry it
with the same `idempotency_key`**: you'll be charged at most once. Use a **new,
unique** key (e.g. a UUID) for each *new* top-up. If you omit it, every call is
an independent charge — so an accidental double-call charges twice.
## Responses
**200 — charged, credits already applied**
```json
{ "charged": true, "balance_updated": true, "credits_added": 5000, "new_balance": 5200 }
```
**200 — charged, credits still being applied** (re-check the balance endpoint shortly)
```json
{ "charged": true, "balance_updated": false, "credits_added": 5000,
"new_balance": 200, "reason": "Payment captured. Credits are being applied..." }
```
**400 — could not charge a saved card** (no card on file, declined, or extra
verification needed). Open `billing_url` (the Explee billing page), add a card,
then retry the top-up.
```json
{ "charged": false, "billing_url": "https://explee.com/billing",
"reason": "No saved card on file. Add a card on your billing page, then retry." }
```
**429 — daily top-up limit reached** ($10,000 / 24h per organization). Nothing was
charged; retry later.
```json
{ "charged": false, "reason": "Daily top-up limit reached ($10,000 / 24h). Try again later." }
```
`422` — `credits` outside the 500–100000 range, or `idempotency_key` too long.
Request Body
Request body required
Responses
200: Successful Response401: Invalid or missing API key. Include `X-API-Key` header.402: Insufficient credit balance. Top up your account.422: Validation error. Check request body and parameters.429: Rate limit exceeded (10000/hour) or concurrent limit reached (150 per organization).500: Internal server error. Contact support if persists.504: Request timeout. Please try again later.
GET /public/api/v1/billing/balance
Get balance
> ⚠️ **Restricted access** — the billing API is enabled per organization. If you
> get a `403`, request access via [email protected].
Return your organization's net credit balance — the same number shown on the
Explee dashboard.
Poll this to decide when to top up — when `remain` drops below the threshold you
need for upcoming requests, call `POST /public/api/v1/billing/topup`.
## Response
```json
{ "remain": 4200 }
```
`remain` is the net balance in credits (1 credit = $0.01): prepaid funds minus
any active postpaid (AutoGTM) usage that hasn't been collected yet. It can be
**negative** if the org is carrying postpaid debt.
Responses
200: Successful Response401: Invalid or missing API key. Include `X-API-Key` header.402: Insufficient credit balance. Top up your account.422: Validation error. Check request body and parameters.429: Rate limit exceeded (10000/hour) or concurrent limit reached (150 per organization).500: Internal server error. Contact support if persists.504: Request timeout. Please try again later.
GET /public/api/v1/autogtm/projects
List AutoGTM projects
List the AutoGTM projects owned by your organization.
Authenticated by the same `X-API-Key` as the rest of this API — the key resolves
to your organization, and its active projects are returned newest first.
**Response:**
- `projects` — active projects with `id`, `domain` (the project's identity in
the app), and `daily_budget_usd` (the project-wide daily budget anchor,
`null` when not set).
- `total` — number of projects returned.
Use a project `id` to filter the campaigns list
(`GET /public/api/v1/autogtm/campaigns?project_id=…`).
Responses
200: Successful Response401: Invalid or missing API key. Include `X-API-Key` header.402: Insufficient credit balance. Top up your account.422: Validation error. Check request body and parameters.429: Rate limit exceeded (10000/hour) or concurrent limit reached (150 per organization).500: Internal server error. Contact support if persists.504: Request timeout. Please try again later.
GET /public/api/v1/autogtm/campaigns
List AutoGTM campaigns
List the AutoGTM campaigns owned by your organization.
Authenticated by the same `X-API-Key` as the rest of this API — the key resolves
to your organization, and campaigns are returned across all of its projects.
Pass `project_id` (see `GET /public/api/v1/autogtm/projects`) to get one
project's campaigns only.
**Response:**
- `campaigns` — non-archived campaigns with `id`, `project_id`, `name`,
`target_url`, `daily_limit_usd`, and lifecycle `status`.
- `total` — number of campaigns returned.
Use a campaign `id` to scope follow-up management calls (inbox replies, budget,
start/stop, analytics).
Parameters
project_id (query, optional): Return only this project's campaigns (see `GET /public/api/v1/autogtm/projects`).
Responses
200: Successful Response401: Invalid or missing API key. Include `X-API-Key` header.402: Insufficient credit balance. Top up your account.422: Validation error. Check request body and parameters.429: Rate limit exceeded (10000/hour) or concurrent limit reached (150 per organization).500: Internal server error. Contact support if persists.504: Request timeout. Please try again later.404: Unknown `project_id` (or not your project).
POST /public/api/v1/autogtm/campaigns/import
Create a campaign from your own leads (import)
Create a new campaign from your own lead list (async).
Each call creates a **new** campaign in the given project — the campaign is
built for your leads only (no agent lead discovery) and starts sending
automatically once live, within your project budget.
**How it works:**
1. Submit `project_id`, a campaign `name`, and up to 30,000 `leads`
2. Receive a `task_id` immediately
3. Poll `GET /public/api/v1/autogtm/campaigns/import/{task_id}` until `completed`
4. `result.campaign_id` is your new campaign — it appears in the campaigns list
**Per lead** — mandatory: `email`, `first_name`, `last_name`, `company_domain`,
`job_title`; recommended: `linkedin_url` (enriches the lead from Explee's
contact base for a richer email). Leads missing mandatory fields are skipped
(reported in the result), never a request-level error. Duplicates of leads
already contacted in the project and do-not-contact entries are dropped.
**Pricing:** the import itself is free. Emails are verified at send time at
Explee's cost; sending is billed as usual.
Request Body
Request body required
Responses
200: Successful Response401: Invalid or missing API key. Include `X-API-Key` header.402: Insufficient credit balance. Top up your account.422: Validation error. Check request body and parameters.429: Too many pending imports.500: Internal server error. Contact support if persists.504: Request timeout. Please try again later.404: Unknown `project_id` (or not your project).
GET /public/api/v1/autogtm/campaigns/import/{task_id}
Campaign import status/result
Check status and retrieve the result of a campaign import.
**Statuses:**
- `pending` — import in progress; `progress` shows the current stage. Poll
every few seconds.
- `completed` — done; `result.campaign_id` is the new campaign (or `null` if
no leads survived validation/dedup — then no campaign was created).
- `failed` — see `error`.
Parameters
task_id (path, required): Task ID returned from the import POST.
Responses
200: Successful Response401: Invalid or missing API key. Include `X-API-Key` header.402: Insufficient credit balance. Top up your account.422: Validation error. Check request body and parameters.429: Rate limit exceeded (10000/hour) or concurrent limit reached (150 per organization).500: Internal server error. Contact support if persists.504: Request timeout. Please try again later.404: Import task not found.
GET /public/api/v1/autogtm/hot-leads
List hot leads
Every **hot lead** across your organization — people who replied to your
outreach with real interest — newest first, as enriched contacts ready to
map into CRM fields.
**Polling:** pass `since` (ISO 8601) with your last poll time to get only
leads that went hot after it — the Zapier/Make pattern. `became_hot_at` of
the newest item is your next cursor.
A lead leaves the feed when you dismiss it in the inbox («Not a hot lead»)
or when it later unsubscribes. To read the full conversation or answer:
`GET /autogtm/campaigns/{campaign_id}/inbox/{person_id}` and `…/reply`.
Parameters
campaign_id (query, optional): Only this campaign. Omit for the whole organization.since (query, optional): Only leads that became hot at/after this time (ISO 8601). Use for polling.limit (query, optional): Page size.offset (query, optional): Pagination offset.
Responses
200: Successful Response401: Invalid or missing API key. Include `X-API-Key` header.402: Insufficient credit balance. Top up your account.422: Validation error. Check request body and parameters.429: Rate limit exceeded (10000/hour) or concurrent limit reached (150 per organization).500: Internal server error. Contact support if persists.504: Request timeout. Please try again later.404: `campaign_id` not found or not owned by your organization.
GET /public/api/v1/autogtm/campaigns/{campaign_id}/inbox
List inbox conversations
List the campaign's conversations (contacted people), most recent first.
**Tabs:** `need_reply` — replies awaiting a human answer (start here),
`replied` — everyone who replied, `sent` — everyone contacted. Omit for the
full universe.
Parameters
campaign_id (path, required)tab (query, optional): Filter: `need_reply`, `replied` or `sent`. Omit for all.limit (query, optional): Page size.offset (query, optional): Pagination offset.
Responses
200: Successful Response401: Invalid or missing API key. Include `X-API-Key` header.402: Insufficient credit balance. Top up your account.422: Validation error. Check request body and parameters.429: Rate limit exceeded (10000/hour) or concurrent limit reached (150 per organization).500: Internal server error. Contact support if persists.504: Request timeout. Please try again later.404: Campaign not found or not owned by your organization.
GET /public/api/v1/autogtm/campaigns/{campaign_id}/inbox/{person_id}
Read a conversation thread
The full conversation with one contact: our outbound emails and their replies,
in order, plus the reply gate (`can_reply`).
To answer, POST to `/reply` with just your message text.
Parameters
campaign_id (path, required)person_id (path, required)
Responses
200: Successful Response401: Invalid or missing API key. Include `X-API-Key` header.402: Insufficient credit balance. Top up your account.422: Validation error. Check request body and parameters.429: Rate limit exceeded (10000/hour) or concurrent limit reached (150 per organization).500: Internal server error. Contact support if persists.504: Request timeout. Please try again later.404: Campaign not found or not owned by your organization.
POST /public/api/v1/autogtm/campaigns/{campaign_id}/inbox/{person_id}/reply
Reply in a thread
Reply to this contact — send just the message text.
You reply to the **lead**, not to an email address: the server resolves the
recipient, the subject (`Re: …`) and the threading from the contact's real
conversation, so a reply can only ever go back to the person who wrote to you —
never to an address you supply. The message goes through the same compliance
gate and content moderation as replies sent from the app.
Allowed only for a contact who has **replied** and isn't `unsubscribe`
— otherwise `403`. You may send at most three replies per message the lead sent
you (`429` if exceeded). The send is recorded under your organization's owner
identity (an API key carries no user).
Parameters
campaign_id (path, required)person_id (path, required)
Request Body
Request body required
Responses
200: Successful Response401: Invalid or missing API key. Include `X-API-Key` header.402: Insufficient credit balance. Top up your account.422: Validation error. Check request body and parameters.429: Too many replies to this contact in the last 24h.500: Internal server error. Contact support if persists.504: Request timeout. Please try again later.404: Campaign not found or not owned by your organization.403: Reply blocked: `unsubscribe` thread, or the contact never replied.
GET /public/api/v1/autogtm/campaigns/{campaign_id}/inbox/{person_id}/note
Read the lead note
The team-shared note on this lead — the same free-text field your team sees
and edits in the AutoGTM inbox (Lead info panel). `note` is `null` when no
note has been set.
Parameters
campaign_id (path, required)person_id (path, required)
Responses
200: Successful Response401: Invalid or missing API key. Include `X-API-Key` header.402: Insufficient credit balance. Top up your account.422: Validation error. Check request body and parameters.429: Rate limit exceeded (10000/hour) or concurrent limit reached (150 per organization).500: Internal server error. Contact support if persists.504: Request timeout. Please try again later.404: Campaign or lead not found, or not owned by your organization.
POST /public/api/v1/autogtm/campaigns/{campaign_id}/inbox/{person_id}/note
Set the lead note
Set (or clear) the lead's team-shared note. The note is one shared text per
lead, last-write-wins — a write here replaces what a teammate typed in the
app, and vice versa.
Pass `{"note": null}` (or an empty string) to clear it.
Parameters
campaign_id (path, required)person_id (path, required)
Request Body
Request body required
Responses
200: Successful Response401: Invalid or missing API key. Include `X-API-Key` header.402: Insufficient credit balance. Top up your account.422: Validation error. Check request body and parameters.429: Rate limit exceeded (10000/hour) or concurrent limit reached (150 per organization).500: Internal server error. Contact support if persists.504: Request timeout. Please try again later.404: Campaign or lead not found, or not owned by your organization.
GET /public/api/v1/autogtm/projects/{project_id}/budget
Get project daily budget
Read the project's total daily outreach budget (the anchor the dashboard
slider sets).
Per-campaign allocations are derived from this number automatically — see
`daily_limit_usd` on each campaign in `GET /autogtm/campaigns`.
Parameters
project_id (path, required)
Responses
200: Successful Response401: Invalid or missing API key. Include `X-API-Key` header.402: Insufficient credit balance. Top up your account.422: Validation error. Check request body and parameters.429: Rate limit exceeded (10000/hour) or concurrent limit reached (150 per organization).500: Internal server error. Contact support if persists.504: Request timeout. Please try again later.404: Project not found or not owned by your organization.
PATCH /public/api/v1/autogtm/projects/{project_id}/budget
Set project daily budget
Set the project's total daily outreach budget.
The change is spread across the project's active campaigns proportionally —
exactly what the dashboard slider does. **`0` pauses all sending** while
keeping campaigns configured (the explicit off switch).
Parameters
project_id (path, required)
Request Body
Request body required
Responses
200: Successful Response401: Invalid or missing API key. Include `X-API-Key` header.402: Insufficient credit balance. Top up your account.422: Validation error. Check request body and parameters.429: Rate limit exceeded (10000/hour) or concurrent limit reached (150 per organization).500: Internal server error. Contact support if persists.504: Request timeout. Please try again later.404: Project not found or not owned by your organization.
PATCH /public/api/v1/autogtm/campaigns/{campaign_id}/budget
Set campaign daily budget
Set one campaign's daily budget.
The campaign's `daily_limit_usd` is set directly and the project's total daily
budget follows as the sum of its running campaigns — the other campaigns are not
touched (grow or shrink the total spend, not redistribute a fixed one).
**Editable only while Autopilot is OFF** (`GET/PATCH …/projects/{id}/autopilot`):
while it's ON the agent owns the split and this returns `409`. A paused / not-yet-
running campaign holds no allocation, so setting its budget also returns `409` —
resume it first. To set the whole-project budget instead, use
`PATCH …/projects/{id}/budget`.
Parameters
campaign_id (path, required)
Request Body
Request body required
Responses
200: Successful Response401: Invalid or missing API key. Include `X-API-Key` header.402: Insufficient credit balance. Top up your account.422: Validation error. Check request body and parameters.429: Rate limit exceeded (10000/hour) or concurrent limit reached (150 per organization).500: Internal server error. Contact support if persists.504: Request timeout. Please try again later.404: Campaign not found or not owned by your organization.409: Autopilot is ON (budget is agent-managed) or the campaign is not running.
POST /public/api/v1/autogtm/campaigns/{campaign_id}/stop
Stop campaign
Stop a campaign **from any status**, idempotently: interrupts a running lead
search, cancels queued outreach emails, and freezes a pending review's
auto-approve countdown. Nothing sends until you start it again.
Parameters
campaign_id (path, required)
Responses
200: Successful Response401: Invalid or missing API key. Include `X-API-Key` header.402: Insufficient credit balance. Top up your account.422: Validation error. Check request body and parameters.429: Rate limit exceeded (10000/hour) or concurrent limit reached (150 per organization).500: Internal server error. Contact support if persists.504: Request timeout. Please try again later.404: Campaign not found or not owned by your organization.
POST /public/api/v1/autogtm/campaigns/{campaign_id}/start
Start campaign
Re-enable a stopped campaign — the status-aware inverse of stop:
- stopped while sending → resumes sending (requires an affordable balance);
- stopped in review → un-freezes the review countdown;
- stopped during lead search → re-runs the search.
Already-running or archived campaigns are a no-op.
**Note:** the AutoGTM autopilot also manages campaigns. If it is enabled for
the project, it may later re-balance what you start or stop here.
Parameters
campaign_id (path, required)
Responses
200: Successful Response401: Invalid or missing API key. Include `X-API-Key` header.402: Insufficient credit balance. Top up your account.422: Validation error. Check request body and parameters.429: Rate limit exceeded (10000/hour) or concurrent limit reached (150 per organization).500: Internal server error. Contact support if persists.504: Request timeout. Please try again later.404: Campaign not found or not owned by your organization.
GET /public/api/v1/autogtm/campaigns/{campaign_id}/analytics
Campaign analytics
Campaign performance for a period: emails sent, replies, reply rate, hot leads,
spend, cost per lead, budget allocation, the leads pool and the manual lead
funnel. The same numbers the AutoGTM dashboard shows — use them to drive your
own budget/start/stop decisions.
Parameters
campaign_id (path, required)period (query, optional): Aggregation window.
Responses
200: Successful Response401: Invalid or missing API key. Include `X-API-Key` header.402: Insufficient credit balance. Top up your account.422: Validation error. Check request body and parameters.429: Rate limit exceeded (10000/hour) or concurrent limit reached (150 per organization).500: Internal server error. Contact support if persists.504: Request timeout. Please try again later.404: Campaign not found or not owned by your organization.
GET /public/api/v1/autogtm/projects/{project_id}/analytics
Project analytics
Project-level performance for a period: the aggregate totals (emails, replies,
reply rate, hot leads, spend) plus the per-campaign breakdown — exactly what the
AutoGTM dashboard shows for a project. Both the totals and the per-campaign rows
cover the requested `period`.
Parameters
project_id (path, required)period (query, optional): Aggregation window.
Responses
200: Successful Response401: Invalid or missing API key. Include `X-API-Key` header.402: Insufficient credit balance. Top up your account.422: Validation error. Check request body and parameters.429: Rate limit exceeded (10000/hour) or concurrent limit reached (150 per organization).500: Internal server error. Contact support if persists.504: Request timeout. Please try again later.404: Project not found or not owned by your organization.
GET /public/api/v1/autogtm/projects/{project_id}/autopilot
Get autopilot settings
Read the project's autopilot and auto-reply settings.
- `autopilot_enabled` — the AutoGTM autopilot agent. While ON it manages
campaigns and the per-campaign budget split (per-campaign budget edits return
409); turn it OFF to control budgets yourself.
- `auto_reply_enabled` / `auto_reply_delay_minutes` — AI auto-reply behaviour.
- `reply_cc_emails` — project defaults added to CC on every manual or automatic reply.
Parameters
project_id (path, required)
Responses
200: Successful Response401: Invalid or missing API key. Include `X-API-Key` header.402: Insufficient credit balance. Top up your account.422: Validation error. Check request body and parameters.429: Rate limit exceeded (10000/hour) or concurrent limit reached (150 per organization).500: Internal server error. Contact support if persists.504: Request timeout. Please try again later.404: Project not found or not owned by your organization.
PATCH /public/api/v1/autogtm/projects/{project_id}/autopilot
Set autopilot settings
Update the project's autopilot / auto-reply settings. Send only the fields you
want to change — at least one is required.
Turning `autopilot_enabled` **off** hands per-campaign budgets back to you
(`PATCH …/campaigns/{id}/budget` stops returning 409); turning it **on** makes
them agent-managed again.
Parameters
project_id (path, required)
Request Body
Request body required
Responses
200: Successful Response401: Invalid or missing API key. Include `X-API-Key` header.402: Insufficient credit balance. Top up your account.422: No fields to update.429: Rate limit exceeded (10000/hour) or concurrent limit reached (150 per organization).500: Internal server error. Contact support if persists.504: Request timeout. Please try again later.404: Project not found or not owned by your organization.
POST /public/api/v1/feedback
Send feedback
Send us freeform feedback about the API: request a feature, report a problem,
tell us data is missing or wrong — anything, in your own words.
The message lands directly with the Explee team. We read everything, though we
don't guarantee an individual reply. No credits are charged.
Request Body
Request body required
Responses
200: Successful Response401: Invalid or missing API key. Include `X-API-Key` header.422: Validation error. Check request body and parameters.429: Rate limit exceeded (10000/hour) or concurrent limit reached (150 per organization).500: Internal server error. Contact support if persists.504: Request timeout. Please try again later.
GET /public/api/v1/dedup/people
People Lists
Responses
200: Successful Response401: Invalid or missing API key. Include `X-API-Key` header.402: Insufficient credit balance. Top up your account.422: Validation error. Check request body and parameters.429: Rate limit exceeded (10000/hour) or concurrent limit reached (150 per organization).500: Internal server error. Contact support if persists.504: Request timeout. Please try again later.
POST /public/api/v1/dedup/people
Create People List
Create an immutable list of people you already own. Pass the person objects returned by people search or
find-and-enrich in `people`; they are matched by LinkedIn URL, normalized email, or first name + last name +
company domain. Existing integrations can keep using the legacy `linkedin_urls` field.
Pass the returned id in `exclude_lists` on people search — matched people are not returned and not charged.
Lists can't be modified: to grow your ledger, create a new list per batch and pass all ids;
consolidate periodically. URLs are normalized on write; unparseable values are skipped and reported.
**Limits:** 100,000 values per list; per search request: 100 lists, 500,000 values combined.
Request Body
Request body required
Responses
200: Successful Response401: Invalid or missing API key. Include `X-API-Key` header.402: Insufficient credit balance. Top up your account.422: Validation error. Check request body and parameters.429: Rate limit exceeded (10000/hour) or concurrent limit reached (150 per organization).500: Internal server error. Contact support if persists.504: Request timeout. Please try again later.
GET /public/api/v1/dedup/people/{list_id}
Get People List
Returns the list metadata and all stored values.
Parameters
list_id (path, required): Dedup list id (returned on creation).
Responses
200: Successful Response401: Invalid or missing API key. Include `X-API-Key` header.402: Insufficient credit balance. Top up your account.422: Validation error. Check request body and parameters.429: Rate limit exceeded (10000/hour) or concurrent limit reached (150 per organization).500: Internal server error. Contact support if persists.504: Request timeout. Please try again later.404: Dedup list not found.
DELETE /public/api/v1/dedup/people/{list_id}
Delete People List
Removes the whole list. Excluded people will appear (and be charged) in search results again.
Parameters
list_id (path, required): Dedup list id (returned on creation).
Responses
200: Successful Response401: Invalid or missing API key. Include `X-API-Key` header.402: Insufficient credit balance. Top up your account.422: Validation error. Check request body and parameters.429: Rate limit exceeded (10000/hour) or concurrent limit reached (150 per organization).500: Internal server error. Contact support if persists.504: Request timeout. Please try again later.404: Dedup list not found.
GET /public/api/v1/dedup/companies
Companies Lists
Responses
200: Successful Response401: Invalid or missing API key. Include `X-API-Key` header.402: Insufficient credit balance. Top up your account.422: Validation error. Check request body and parameters.429: Rate limit exceeded (10000/hour) or concurrent limit reached (150 per organization).500: Internal server error. Contact support if persists.504: Request timeout. Please try again later.
POST /public/api/v1/dedup/companies
Create Companies List
Create an immutable list of companies you already own (`domain` values from search results).
Pass the returned id in `exclude_lists` on companies search — matched companies are not returned and not charged.
Lists can't be modified: to grow your ledger, create a new list per batch and pass all ids;
consolidate periodically. Domains are normalized on write; unparseable values are skipped and reported.
**Limits:** 100,000 values per list; per search request: 100 lists, 500,000 values combined.
Request Body
Request body required
Responses
200: Successful Response401: Invalid or missing API key. Include `X-API-Key` header.402: Insufficient credit balance. Top up your account.422: Validation error. Check request body and parameters.429: Rate limit exceeded (10000/hour) or concurrent limit reached (150 per organization).500: Internal server error. Contact support if persists.504: Request timeout. Please try again later.
GET /public/api/v1/dedup/companies/{list_id}
Get Companies List
Returns the list metadata and all stored values.
Parameters
list_id (path, required): Dedup list id (returned on creation).
Responses
200: Successful Response401: Invalid or missing API key. Include `X-API-Key` header.402: Insufficient credit balance. Top up your account.422: Validation error. Check request body and parameters.429: Rate limit exceeded (10000/hour) or concurrent limit reached (150 per organization).500: Internal server error. Contact support if persists.504: Request timeout. Please try again later.404: Dedup list not found.
DELETE /public/api/v1/dedup/companies/{list_id}
Delete Companies List
Removes the whole list. Excluded companies will appear (and be charged) in search results again.
Parameters
list_id (path, required): Dedup list id (returned on creation).
Responses
200: Successful Response401: Invalid or missing API key. Include `X-API-Key` header.402: Insufficient credit balance. Top up your account.422: Validation error. Check request body and parameters.429: Rate limit exceeded (10000/hour) or concurrent limit reached (150 per organization).500: Internal server error. Contact support if persists.504: Request timeout. Please try again later.404: Dedup list not found.