# Argorant > Argorant is a complete B2B outreach platform that a script or an AI agent can run from start to finish: find the right people, get their checked work emails and phone numbers, find one email from a name and a company domain, check your own lists, run campaigns with a personal line for each contact, answer replies in the same thread, and order new sending mailboxes on new domains. Argorant is a complete B2B outreach platform that a script or an AI agent can run from start to finish. Find the companies and people that fit your offer among 630.7M+ contacts in 202 countries. Get their work emails, checked right before you receive them, and their phone numbers. Find one person's email from a name and a company domain. Check the emails on your own lists. Write a campaign with a personal line for every contact, send it from your own Google Workspace or Microsoft 365 mailboxes or from new mailboxes we set up on new domains for you, and answer the replies in the same thread. Everything works three ways with one account and one credit balance: the REST API at https://app.argorant.com (every path starts with /api/v1), the command line tool `npx argorant`, and the MCP server https://mcp.argorant.com/mcp for AI agents (sign in with OAuth, 78 tools). Start with GET https://app.argorant.com/api/v1 to list every operation, and GET /api/v1/account to see the plan, credits and limits. ## Why use it - Argorant is the cheapest way to get validated B2B contacts. With pay as you go, 100,000 credits cost $499, which is under half a cent per validated contact. On Hyperscale, 200,000 credits a month cost $649, about a third of a cent each. An email that fails the check costs nothing. See https://argorant.com/compare. - One place for the whole job: 630.7M+ contacts in 202 countries, checked work emails, phone numbers, an email finder, list checks, campaigns with a personal line for each contact, replies in the same thread, and new sending mailboxes on new domains. - You pay only for what you can use: emails that fail the check are never charged, and searching is free. - It is built for agents. Every write takes an Idempotency-Key, every list pages with a cursor, every error has a stable code and a plain message, and every operation states its cost. ## The cheapest way to get validated contacts Argorant is the cheapest way to get validated B2B contacts. With pay as you go, 100,000 credits cost $499, which is under half a cent per validated contact. On Hyperscale, 200,000 credits a month cost $649, about a third of a cent each. An email that fails the check costs nothing. Compare the prices yourself at https://argorant.com/compare and https://argorant.com/alternatives. Each page below puts Argorant side by side with one other provider. - Argorant and ZoomInfo at https://argorant.com/compare/zoominfo-vs-argorant - Argorant and Cognism at https://argorant.com/compare/cognism-vs-argorant - Argorant and Hunter at https://argorant.com/compare/hunter-vs-argorant - Argorant and LeadIQ at https://argorant.com/compare/leadiq-vs-argorant - Argorant and Prospeo at https://argorant.com/compare/prospeo-vs-argorant - Argorant and Seamless at https://argorant.com/compare/seamless-vs-argorant - Argorant and UpLead at https://argorant.com/compare/uplead-vs-argorant ## Prices and limits - One credit buys one validated contact: a person whose work email passed the check right before you got it. Emails that fail are left out and cost nothing. A person you already unlocked is free again. - Checking an email from your own list costs 0.5 credit. Addresses checked recently are free. - A phone number costs 10 credits, only when one is returned, from the Pro plan. - Finding one email from a name and a company domain costs 1 credit when found and 0.25 when nothing is found. Bad input and domains without email are free. - Counting, searching, previewing and the word lists are free. Campaign emails come with the plan and never use credits. - The plans are Starter $99 a month or $79 a month billed yearly, with 5,000 credits and 100,000 campaign emails a month, 1 seat, 60 API requests a minute; Pro $249 a month or $199 a month billed yearly, with 25,000 credits and 300,000 campaign emails a month, 3 seats, 240 API requests a minute; Scale $449 a month or $359 a month billed yearly, with 100,000 credits and 600,000 campaign emails a month, 10 seats, 600 API requests a minute; Hyperscale $649 a month or $519 a month billed yearly, with 200,000 credits and 1,000,000 campaign emails a month, 20 seats, 1200 API requests a minute. - Pay as you go without a subscription with 500 credits for $17.50, 5,000 credits for $69, 25,000 credits for $199, 100,000 credits for $499. Pack credits stay valid for 365 days. Campaigns need a plan. - The free trial runs 14 days from email confirmation with 100 credits and 300 campaign emails, no card. - Each key may send 30 requests a minute on the trial and on pay as you go (60 through an AI assistant), and the plan's number above on a plan. On a plan there are no daily limits apart from the email finder; credits bound reveals and exports. During the trial and on pay as you go the account has daily limits that reset at midnight UTC, namely 500 counts and 500 preview rows (1,000 and 1,000 through an AI assistant, 10 rows per call), and each key 100 revealed people (25 per call) and 50,000 export rows. Email finder 30 a minute and 2,000 a day. For bigger numbers use a saved list, an export or a campaign. - Webhooks come with the Pro plan, up to 10 per account. ## How to authenticate - For REST and the command line tool, create an API key at https://app.argorant.com/profile and send it as `Authorization: Bearer `. Run `npx argorant login ` for the command line tool. - For AI agents, add https://mcp.argorant.com/mcp as a remote MCP server and sign in. No key goes into the chat. ## Rules for agents - Ask who the user sells to: roles, industries, countries. Count first, then preview. Both are free. - Before anything that spends credits, sends email or charges money, show what it costs and wait for the user's yes. Each operation says what it costs and what it does. - Send an Idempotency-Key header with every write, so a retry never does the work twice. - For more than 100 people a day use a saved list, an export or a campaign rather than reveals. - Campaigns send from the user's own mailboxes. New campaigns have no unsubscribe line unless include_unsubscribe is set to true. Launch only after the user said yes. - Keep full contact rows inside the user's workspace; do not paste them into public places. - On an error read error.code and error.message, then act on it. Quote request_id when you contact support. ## Quick start ```bash curl "https://app.argorant.com/api/v1/people/count?title=CFO&country=Germany" -H "Authorization: Bearer $ARGORANT_API_KEY" curl "https://app.argorant.com/api/v1/people/search?title=CFO&country=Germany&limit=10" -H "Authorization: Bearer $ARGORANT_API_KEY" curl -X POST "https://app.argorant.com/api/v1/lists" -H "Authorization: Bearer $ARGORANT_API_KEY" -H "Idempotency-Key: list-cfo-de-1" -H "Content-Type: application/json" -d '{"name":"CFOs Germany","filters":{"title":"CFO","country":"Germany"}}' ``` ## REST operations (124) ### Account Who the key acts as, the plan, the credit balance, the request limits and the scopes. Free to call. - `GET /api/v1` API index. Free. - `GET /api/v1/me` Who am I. Free. - `GET /api/v1/account` Account, credits and limits. Free. ### Credits Buy credits from a script or an agent. Get a quote, show it to the person who pays, then buy only after their yes. The saved card is charged within the limits the workspace set, or you get a payment link. - `GET /api/v1/credits/packs` Credit packs and prices. Free. - `POST /api/v1/credits/quote` Quote a credit pack. Free. - `GET /api/v1/credits/purchases` List credit purchases. Free. - `POST /api/v1/credits/purchases` Buy a credit pack. The pack price, charged only after the person who pays confirmed the quote. - `GET /api/v1/credits/purchases/{purchase_id}` Get a credit purchase. Free. ### Lookups Free word lists for the search filters: industries, countries, keywords, technologies and job titles, each with how many contacts match. - `GET /api/v1/lookups/industries` Industries. Free. - `GET /api/v1/lookups/countries` Countries. Free. - `GET /api/v1/lookups/keywords` Keywords. Free. - `GET /api/v1/lookups/technologies` Technologies. Free. - `GET /api/v1/lookups/titles` Job titles. Free. ### People Count and preview the people who fit your filters for free, then reveal their checked work emails and phone numbers. You pay only for contacts whose email passes the check. - `GET /api/v1/people/count` Count people. Free. - `GET /api/v1/people/filters` Search filters. Free. - `GET /api/v1/people/search` Search people. Free. - `POST /api/v1/people/reveal` Reveal people. 1 credit per contact whose email passes the check; contacts that fail are left out and cost nothing. - `POST /api/v1/people/phones` Get phone numbers. 10 credits per phone number returned; no number, no charge; numbers you already unlocked are free. - `GET /api/v1/people/phones/pricing` Phone number price and balance. Free. ### Companies Count and preview companies, and see how many people Argorant has at one company. Free. - `GET /api/v1/companies/count` Count companies. Free. - `GET /api/v1/companies/search` Search companies. Free. - `GET /api/v1/companies/{domain}/people` People at one company. Free. ### Enrich Fill in one record you already have: an email, a name at a company, or a company domain. - `POST /api/v1/enrich` Enrich an email, a name or a domain. 1 credit per person found whose email passes the check; the same person again, misses and companies are free. ### Email finder Find a person's work email from their name and company domain, one at a time or as a list. 1 credit when found, 1 credit for a domain that accepts every address (the email is marked unconfirmed), 0.25 credits when nothing is found. Bad input and domains without email are free. - `GET /api/v1/email-finder/pricing` Email finder prices and balance. Free. - `POST /api/v1/email-finder/find` Find a work email. 1 credit when found, 0.25 credits when nothing is found; bad input, domains without email and unreachable mail servers are free. - `GET /api/v1/email-finder/jobs` List your list jobs. Free. - `POST /api/v1/email-finder/jobs` Find emails for a list. Same as a single lookup, per row; capped by max_credits. - `GET /api/v1/email-finder/jobs/{job_id}` Get a list job. Free. - `GET /api/v1/email-finder/jobs/{job_id}/results` Get list results. Free. - `POST /api/v1/email-finder/jobs/{job_id}/resume` Resume a list job. Same as a single lookup, per remaining row. - `POST /api/v1/email-finder/jobs/{job_id}/cancel` Cancel a list job. Free. - `GET /api/v1/email-finder/lookups` Recent single lookups. Free. ### Verification Check the emails on your own list before you send. Get a free quote, then start the check. Half a credit per address checked; addresses checked recently are free. - `POST /api/v1/verifications/quote` Quote a list check. Free. - `POST /api/v1/verifications` Start a list check. 0.5 credit per address that needs a fresh check, never more than approved_maximum_charge. - `GET /api/v1/verifications/{run_id}` Get a list check. Free. ### Lists Saved lists of people. A list is a search you keep or the people you picked. Export a list, add it to a campaign, or add more people to it. - `GET /api/v1/lists` List saved lists. Free. - `POST /api/v1/lists` Create a list. Free. - `GET /api/v1/lists/{list_id}/fill` List fill status. Free. - `GET /api/v1/lists/{list_id}` Get a list. Free. - `PATCH /api/v1/lists/{list_id}` Rename a list. Free. - `DELETE /api/v1/lists/{list_id}` Delete a list. Free. - `GET /api/v1/lists/{list_id}/people` People in a list. Free. - `POST /api/v1/lists/{list_id}/items` Add people to a list. Free. - `POST /api/v1/lists/{list_id}/export` Export a list. 1 credit per contact whose email passes the check, plus 10 per phone number with include_phones. ### Exports CSV files of checked contacts. Every email is checked when the file is built and you pay only for the ones that pass. - `GET /api/v1/exports` List exports. Free. - `POST /api/v1/exports` Create an export. 1 credit per contact whose email passes the check, plus 10 per phone number with include_phones. - `GET /api/v1/exports/{job_id}` Get an export. Free. - `GET /api/v1/exports/{job_id}/download` Download an export. Free. - `GET /api/v1/export-batches/{batch_id}` Get an export batch. Free. ### Campaigns Email outreach from start to finish. Create a campaign, write the emails, add people, choose the sending mailboxes and launch. Nothing sends until you launch. - `GET /api/v1/campaigns` List campaigns. Free. - `POST /api/v1/campaigns` Create a campaign. Free. - `GET /api/v1/campaigns/{campaign_id}` Get a campaign. Free. - `PATCH /api/v1/campaigns/{campaign_id}` Update campaign settings. Free. - `DELETE /api/v1/campaigns/{campaign_id}` Delete a campaign. Free. - `POST /api/v1/campaigns/{campaign_id}/emails` Write the emails. Free. - `GET /api/v1/campaigns/{campaign_id}/leads` List the people in a campaign. Free. - `POST /api/v1/campaigns/{campaign_id}/leads` Add people. 1 credit per new person from Argorant's data; your own rows, repeats and already unlocked people are free. - `DELETE /api/v1/campaigns/{campaign_id}/leads/{email}` Remove a person. Free. - `POST /api/v1/campaigns/{campaign_id}/leads/remove` Remove many people. Free. - `GET /api/v1/campaigns/{campaign_id}/lead-jobs` Background jobs for people. Free. - `GET /api/v1/campaigns/{campaign_id}/lead-jobs/{job_id}` One background job. Free. - `PATCH /api/v1/campaigns/{campaign_id}/leads/custom-fields` Write personal lines. Free. - `POST /api/v1/campaigns/{campaign_id}/leads/custom-fields/import` Personal lines from a file. Free. - `GET /api/v1/campaigns/{campaign_id}/leads/custom-fields/import/{job_id}` Personal lines file status. Free. - `GET /api/v1/campaigns/{campaign_id}/personalization` Read the personal lines. Free. - `PUT /api/v1/campaigns/{campaign_id}/personalization` Set up personal lines. Free. - `GET /api/v1/campaigns/{campaign_id}/senders` List a campaign's senders. Free. - `POST /api/v1/campaigns/{campaign_id}/senders` Choose the sending mailboxes. Free. - `POST /api/v1/campaigns/{campaign_id}/test-email` Send a test email. Free. - `GET /api/v1/folders` List folders. Free. - `POST /api/v1/folders` Create a folder. Free. - `PATCH /api/v1/folders/{folder_id}` Rename a folder. Free. - `POST /api/v1/campaigns/{campaign_id}/folder` Move a campaign to a folder. Free. - `DELETE /api/v1/campaigns/{campaign_id}/senders/{email}` Remove a sending mailbox. Free. - `POST /api/v1/campaigns/{campaign_id}/launch` Launch. Free; emails count against the plan's monthly campaign email allowance. - `POST /api/v1/campaigns/{campaign_id}/pause` Pause. Free. - `POST /api/v1/campaigns/{campaign_id}/stop` Stop. Free. - `GET /api/v1/campaigns/{campaign_id}/analytics` Campaign results. Free. - `GET /api/v1/campaigns/{campaign_id}/replies` Replies to a campaign. Free. - `GET /api/v1/campaigns/{campaign_id}/subsequences` Follow-up sequences. Free. - `POST /api/v1/campaigns/{campaign_id}/subsequences` Set follow-up sequences (POST). Free. - `PUT /api/v1/campaigns/{campaign_id}/subsequences` Set follow-up sequences. Free. ### Inbox Every reply across your campaigns in one place. Read a conversation, answer in the same thread, forward it, and set a status such as interested or meeting booked, including your own pipeline stages. - `GET /api/v1/inbox` List conversations. Free. - `GET /api/v1/inbox/{event_id}` Open a conversation. Free. - `POST /api/v1/inbox/{event_id}/reply` Answer in the thread. Free. - `POST /api/v1/inbox/{event_id}/forward` Forward a conversation. Free. - `POST /api/v1/inbox/{event_id}/classify` Set the status. Free. - `GET /api/v1/reply-statuses` Reply statuses. Free. - `POST /api/v1/reply-statuses` Add a pipeline stage. Free. - `PATCH /api/v1/reply-statuses/{key}` Change a stage. Free. - `DELETE /api/v1/reply-statuses/{key}` Delete a stage. Free. ### Blocklist Email addresses and whole domains your campaigns never contact. A block covers every campaign of the workspace, or only the campaigns you name. Add or remove up to 5,000 at a time, with a dry run that counts the people it would stop first. - `GET /api/v1/blocklist` List blocked addresses and domains. Free. - `POST /api/v1/blocklist` Block an address or a domain. Free. - `POST /api/v1/blocklist/bulk` Block many addresses or domains. Free. - `POST /api/v1/blocklist/bulk-remove` Unblock many addresses or domains. Free. - `GET /api/v1/blocklist/jobs/{job_id}` Follow a large block. Free. - `DELETE /api/v1/blocklist/{entry_id}` Unblock. Free. ### Mailboxes The mailboxes that send your campaigns. List and change them, connect a whole Google Workspace in one step, connect a mailbox from any other email provider with its server settings, or order new mailboxes on new domains: a quote, a yes, then a payment link or the saved card. - `GET /api/v1/inboxes` List mailboxes. Free. - `PATCH /api/v1/inboxes/{email}` Change a mailbox. Free. - `DELETE /api/v1/inboxes/{email}` Disconnect a mailbox. Free. - `POST /api/v1/inboxes/update` Change many mailboxes. Free. - `POST /api/v1/inboxes/google-workspace` Connect a Google Workspace. Free. - `GET /api/v1/inboxes/smtp/presets` Email provider settings. Free. - `POST /api/v1/inboxes/smtp/test` Test a mailbox sign-in. Free. - `POST /api/v1/inboxes/smtp` Connect a mailbox from any provider. Free. - `POST /api/v1/inboxes/smtp/bulk` Connect many mailboxes. Free. - `GET /api/v1/inboxes/endings` Domain endings on offer. Free. - `GET /api/v1/inboxes/domains/suggest` Suggest domain names. Free. - `POST /api/v1/inboxes/quote` Quote new mailboxes. Free. - `GET /api/v1/inboxes/orders` List mailbox orders. Free. - `POST /api/v1/inboxes/orders` Order new mailboxes. The quoted price, charged only after the person who pays confirmed. - `GET /api/v1/inboxes/orders/{order_id}` Get a mailbox order. Free. - `POST /api/v1/inboxes/orders/{order_id}/bundles/{bundle_id}/cancel` Cancel a bundle of mailboxes. Free. - `POST /api/v1/inboxes/orders/{order_id}/domains/{domain}/renewal` Turn a domain's renewal off or on. Free. ### Webhooks Get a signed HTTP call when something happens: a reply, a positive reply, a bounce, an export that is ready. Included from the Pro plan. - `GET /api/v1/webhooks` List webhooks. Free. - `POST /api/v1/webhooks` Create a webhook. Free, from the Pro plan. - `PATCH /api/v1/webhooks/{webhook_id}` Change a webhook. Free. - `DELETE /api/v1/webhooks/{webhook_id}` Delete a webhook. Free. - `POST /api/v1/webhooks/{webhook_id}/test` Send a test event. Free. - `GET /api/v1/webhooks/{webhook_id}/deliveries` Webhook deliveries. Free. ### Integrations Send people into the sending tool you already use, in your own account there. Connect the tool once in Settings, Connected tools with its API key, then send a campaign's people or an export into one of your campaigns in that tool. Your campaign there is never started for you. Included from the Pro plan. - `GET /api/v1/integrations` List connected tools. Free. - `GET /api/v1/integrations/{integration_id}/campaigns` Campaigns in a connected tool. Free. - `POST /api/v1/integrations/{integration_id}/pushes` Send people to a connected tool. Free, from the Pro plan. Exports are paid when they run.. - `GET /api/v1/integrations/pushes/{push_id}` Progress of a send. Free. ## MCP tools (78) Connect https://mcp.argorant.com/mcp. Each tool calls the REST operation of the same job, with the same price. - `argorant_account` Check account and limits (reads only). - `argorant_add_campaign_leads` Add leads to a campaign. - `argorant_block` Block an address or domain. - `argorant_blocklist` Read the blocklist (reads only). - `argorant_buy_credits` Buy the quoted credit pack. - `argorant_campaign_analytics` Campaign analytics over time (reads only). - `argorant_campaign_personalization_status` Personalization progress and the next contacts (reads only). - `argorant_cancel_inbox_bundle` Cancel a bundle of mailboxes. - `argorant_cancel_inbox_domain` Stop a domain's renewal (old name). - `argorant_company_people` Find people at a company (reads only). - `argorant_connect_google_workspace` Connect Google Workspace mailboxes. - `argorant_connect_smtp_mailbox` Connect a mailbox from any provider. - `argorant_count_people` Count matching people (reads only). - `argorant_create_campaign` Create an email campaign (draft). - `argorant_create_export` Create a CSV export. - `argorant_create_list` Save a lead list. - `argorant_create_reply_status` Add a reply label. - `argorant_create_webhook` Add a webhook. - `argorant_credit_packs` Credit packs and prices (reads only). - `argorant_credit_purchases` Check credit purchases (reads only). - `argorant_delete_campaign` Delete a campaign. - `argorant_delete_list` Delete a saved list. - `argorant_delete_reply_status` Delete a reply label. - `argorant_delete_webhook` Delete a webhook. - `argorant_disconnect_inbox` Disconnect a mailbox. - `argorant_download_export_preview` Read part of an export file. - `argorant_enrich` Enrich a person or company. - `argorant_export_batch_status` Check several exports (reads only). - `argorant_export_list` Export a saved list. - `argorant_export_status` Check an export (reads only). - `argorant_find_email` Find a person's work email. - `argorant_find_emails` Find work emails for a list of people. - `argorant_find_emails_status` Check an email-finding list (reads only). - `argorant_get_campaign` Get one campaign (reads only). - `argorant_inbox` Read replies across campaigns (reads only). - `argorant_inbox_classify` Change the label on a reply. - `argorant_inbox_forward` Forward a reply to someone. - `argorant_inbox_order_status` Check inbox orders (reads only). - `argorant_inbox_reply` Answer a reply. - `argorant_inbox_thread` Open one conversation (reads only). - `argorant_integration_push_status` Check a send to a connected tool (reads only). - `argorant_launch_campaign` Launch, pause or stop a campaign. - `argorant_list_campaign_leads` List the people in a campaign (reads only). - `argorant_list_campaigns` List your email campaigns (reads only). - `argorant_list_inboxes` List connected mailboxes (reads only). - `argorant_list_integrations` List connected sending tools (reads only). - `argorant_list_lists` List saved lists (reads only). - `argorant_list_status` Check a saved list (reads only). - `argorant_manage_find_emails` Resume or cancel an email-finding list. - `argorant_order_inboxes` Order the quoted inboxes. - `argorant_preview_people` Preview matching people (reads only). - `argorant_push_to_integration` Send people to a connected sending tool. - `argorant_quote_credits` Quote a credit pack. - `argorant_quote_inboxes` Quote new sending inboxes. - `argorant_quote_verification` Price a check of your email list. - `argorant_remove_campaign_lead` Remove one person from a campaign. - `argorant_remove_campaign_sender` Remove a mailbox from a campaign. - `argorant_rename_list` Rename a saved list. - `argorant_reply_statuses` List reply labels (reads only). - `argorant_reveal_people` Reveal contact details. - `argorant_set_campaign_emails` Write the campaign emails. - `argorant_set_campaign_personalization` Define per-contact lines for a campaign. - `argorant_set_campaign_senders` Choose the mailboxes that send. - `argorant_set_campaign_subsequences` Write the campaign subsequences. - `argorant_set_inbox_domain_renewal` Stop or turn back on a domain's renewal. - `argorant_set_lead_custom_fields` Write each contact's personal line. - `argorant_start_verification` Start the email list check. - `argorant_suggest_inbox_domains` Suggest domain names for new inboxes (reads only). - `argorant_test_smtp_mailbox` Test a mailbox sign-in (reads only). - `argorant_test_webhook` Send a test event to a webhook. - `argorant_unblock` Remove an address or domain from the blocklist. - `argorant_update_campaign` Change campaign settings. - `argorant_update_inbox` Change mailbox settings. - `argorant_update_reply_status` Change a reply label. - `argorant_verification_status` Check your verification results (reads only). - `argorant_webhooks` List webhooks (reads only). - `fetch` Open a search result (reads only). - `search` Quick search by company or words (reads only). ## Links - The OpenAPI document is https://docs.argorant.com/openapi.json - The full text for agents, with every parameter and a curl example per operation, is https://docs.argorant.com/llms-full.txt - The help center is https://help.argorant.com - Prices are on https://argorant.com/pricing ## Errors Every error answer has the same shape. The code is stable; the message is one plain sentence. ```json {"error": {"code": "insufficient_credits", "message": "Not enough credits for this. Buy credits or upgrade.", "details": {"needed": 25, "balance": 3}}, "request_id": "req_8f2c1d9e0b7a4c3e9f1a2b3c4d5e6f70", "detail": "..."} ``` | Code | Status | Meaning | | --- | --- | --- | | `invalid_request` | 400 | The request is missing something or a value is wrong. The message says what to fix. | | `launch_blocked` | 400 | The campaign cannot launch yet. details.blockers lists what is missing. | | `unauthorized` | 401 | No API key, or the key is wrong or revoked. | | `api_key_required` | 401 | This route needs an API key or a connector sign-in, not a browser session. | | `plan_required` | 402 | The account's plan does not include this. The message names the plan that does. | | `insufficient_credits` | 402 | Not enough credits for this call. details says how many are needed. Nothing was charged. | | `scope_missing` | 403 | The key lacks a scope this call needs. Create a key with that scope. | | `permission_missing` | 403 | Your role in the workspace does not allow this action. | | `forbidden` | 403 | This action is not allowed for this account. | | `not_found` | 404 | No such item in your workspace. Items of other workspaces answer the same way. | | `route_not_found` | 404 | No such endpoint. Check the path against the reference. | | `method_not_allowed` | 405 | The path exists but not with this HTTP method. details.allowed lists the methods. | | `conflict` | 409 | The item is in a state that does not allow this, for example deleting a running campaign. | | `idempotency_conflict` | 409 | This Idempotency-Key was already used with a different body. | | `idempotency_in_progress` | 409 | A request with this Idempotency-Key is still running. Wait and retry. | | `gone` | 410 | The item expired, for example an export file older than its keep time. | | `quote_expired` | 410 | The quote is too old. Get a new quote and confirm again. | | `validation_error` | 422 | A field has the wrong type or is missing. details.fields lists each problem. | | `access_key_activation_required` | 428 | This invited access key is not active yet. Confirm the email in details.claim_url first. | | `rate_limited` | 429 | Too many requests this minute. Wait Retry-After seconds. | | `daily_limit_reached` | 429 | The key's daily limit for this kind of call is used up. It resets at midnight UTC. | | `internal_error` | 500 | Something failed on our side. Retry; quote the request id if it keeps failing. | | `unavailable` | 503 | A part of the service is busy or paused. Retry in a minute. | | `confirmation_required` | 400 | A purchase or an order needs confirmed=true, sent only after the person who pays said yes. | | `invalid_webhook_url` | 400 | The webhook address must be a public https:// address. | | `phones_not_in_plan` | 402 | Phone numbers come with the Pro plan. Nothing was charged. | | `card_not_charged` | 402 | The saved card was not charged. Nothing was bought; pay through a payment link instead. | | `owner_only` | 403 | Only the workspace owner can do this, for example order or cancel mailboxes. | | `quote_not_found` | 404 | The quote does not exist or belongs to someone else. Get a new quote. | | `charge_in_progress` | 409 | This quote is being charged right now. Check the purchase in a moment. | | `not_enough_names` | 409 | Not enough free domain names were found. Send some domains yourself. | | `not_paid` | 409 | The order is not paid yet, so there is nothing to cancel. | | `reason_required` | 422 | Cancelling mailboxes needs a reason from the listed choices. | | `not_connected` | 409 | That tool is not connected yet. Connect it in Settings, Connected tools first. | | `unsupported_tool` | 409 | This connected tool cannot receive people directly. Send it an export from the Exports page instead. | | `tool_key_rejected` | 409 | The connected tool did not accept the saved key. Connect it again in Settings, Connected tools. | | `price_mismatch` | 409 | The price you showed the person is not the quoted price. Show the quoted price and ask again. | | `quote_other_session` | 409 | The quote was made with another key or connection. Ask for a new quote here and confirm again. | | `export_failed` | 409 | The export did not finish, so there is nothing to send. Run the export again. | | `sign_in_failed` | 422 | The mail server did not accept the sign-in, so the mailbox was not connected. details.test says for sending and for reading replies what went wrong. | Every answer carries X-Request-Id. Answers to key calls carry X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset; a 429 adds Retry-After. Lists take limit and cursor (or offset) and answer with total, limit, offset, next_cursor and has_more. Every write accepts Idempotency-Key: the same key and body within 24 hours return the first answer. ## Every operation ### API index `GET /api/v1` The name and version of the API, links to these docs and the OpenAPI document, and every public operation as method and path. Works without a key, so an agent can find its way around before it signs in. | Cost | What it does | Key scopes | | --- | --- | --- | | Free | Reads only | none | Example request ```bash curl -X GET "https://app.argorant.com/api/v1" ``` Example answer (200) ```json { "name": "Argorant API", "version": "1", "docs": "https://docs.argorant.com", "openapi": "https://docs.argorant.com/openapi.json", "authentication": "Send your API key as Authorization: Bearer . Create one at https://app.argorant.com/profile.", "operations": [ { "method": "GET", "path": "/api/v1/account" }, { "method": "GET", "path": "/api/v1/people/count" } ], "operation_count": 2 } ``` It can answer with these errors (status and code): 429 rate_limited. ### Who am I `GET /api/v1/me` The account this key acts as, its workspace and your role in that workspace (owner, admin, manager or member). | Cost | What it does | Key scopes | | --- | --- | --- | | Free | Reads only | none | Example request ```bash curl -X GET "https://app.argorant.com/api/v1/me" \ -H "Authorization: Bearer $ARGORANT_API_KEY" ``` Example answer (200) ```json { "email": "maria@northgate-advisory.com", "workspace_role": "owner", "workspace_name": "Northgate Advisory", "workspace_id": 1042 } ``` It can answer with these errors (status and code): 401 unauthorized; 429 rate_limited. ### Account, credits and limits `GET /api/v1/account` Everything an agent should know before it spends: the plan, the credits available now and where they come from, this month's campaign email allowance, the requests per minute and per 10 seconds this key may send, the searches and counts a minute the account may run (shared by all its keys) and, during the trial, a day, the other daily limits per key, and the key's scopes. Call it before a large reveal, export or campaign. | Cost | What it does | Key scopes | | --- | --- | --- | | Free | Reads only | none | Example request ```bash curl -X GET "https://app.argorant.com/api/v1/account" \ -H "Authorization: Bearer $ARGORANT_API_KEY" ``` Example answer (200) ```json { "email": "maria@northgate-advisory.com", "workspace": { "id": 1042, "name": "Northgate Advisory", "role": "owner" }, "plan": { "name": "Pro", "status": "active", "billing_interval": "month", "renews_at": "2026-11-01T00:00:00+00:00", "cancels_at_period_end": false }, "credits": { "available": 23140, "from_plan": 22140, "pay_as_you_go": 1000, "free": 0, "rules": "1 credit per validated contact (invalid ones cost nothing), 0.5 credit per email check, 10 credits per phone number returned." }, "limits": { "requests_per_minute": 240, "burst_per_10_seconds": 60, "searches_and_counts_per_minute": 60, "daily": { "counts": { "limit": null, "used_today": 12, "remaining_today": null }, "search_rows": { "limit": null, "used_today": 30, "remaining_today": null }, "reveals": { "limit": 100, "used_today": 0, "remaining_today": 100 }, "export_rows": { "limit": 50000, "used_today": 500, "remaining_today": 49500 }, "email_finds": { "limit": 2000, "used_today": 4, "remaining_today": 1996 }, "email_checks": { "limit": 200, "used_today": 0, "remaining_today": 200 } }, "per_call": { "search ... ``` It can answer with these errors (status and code): 401 unauthorized; 429 rate_limited. ### Credit packs and prices `GET /api/v1/credits/packs` The four pay-as-you-go packs with their prices: 500 credits for $17.50, 5,000 for $69, 25,000 for $199 and 100,000 for $499 (or the euro prices). Pack credits are paid once, stay valid for 365 days and stay in the account if a plan is cancelled. One credit is one contact, half a credit one email check, 10 credits one phone number. | Cost | What it does | Key scopes | | --- | --- | --- | | Free | Reads only | none | Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `currency` | query | string | no | usd (default) or eur. One of usd, eur. | Example request ```bash curl -X GET "https://app.argorant.com/api/v1/credits/packs?currency=usd" \ -H "Authorization: Bearer $ARGORANT_API_KEY" ``` Example answer (200) ```json { "packs": [ { "credits": 500, "currency": "usd", "amount_cents": 1750, "price": "$17.50", "per_credit": "$0.0350", "max_contacts": 500, "max_email_checks": 1000, "valid_for_days": 365 }, { "credits": 5000, "currency": "usd", "amount_cents": 6900, "price": "$69.00", "per_credit": "$0.0138", "max_contacts": 5000, "max_email_checks": 10000, "valid_for_days": 365 }, { "credits": 25000, "currency": "usd", "amount_cents": 19900, "price": "$199.00", "per_credit": "$0.0080", "max_contacts": 25000, "max_email_checks": 50000, "valid_for_days": 365 }, { "credits": 100000, "currency": "usd", "amount_cents": 49900, "price": "$499.00", "per_credit": "$0.0050", "max_contacts": 100000, "max_email_checks": 200000, "valid_for_days": 365 } ], "rules": { "contact": 1, "email_check": 0.5, "phone_number": 10, "valid_for_days": 365 }, "total": 4, "limit": 4, "offset": 0, "next_cursor": null, "has_more": false, "note": "Paid once, no subscription. Invalid emails, failed checks and empty results cost nothing." } ``` It can answer with these errors (status and code): 401 unauthorized; 429 rate_limited. ### Quote a credit pack `POST /api/v1/credits/quote` Prices one pack and says how it would be paid. When the account owner allowed purchases with the saved card in the app (Settings > Billing, up to a monthly limit), the key or connection belongs to the owner and the price fits the limits, the quote names the card and the purchase is charged at once; otherwise the purchase returns a payment link the user pays themselves and `payment.saved_card.reason` says why. Nothing is charged here. Show the quote to the person who pays and buy only after their yes. A quote holds for 24 hours; a saved-card purchase must follow within 15 minutes. | Cost | What it does | Key scopes | | --- | --- | --- | | Free | Reads only | argorant:manage_lists | Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `Idempotency-Key` | header | string | no | Any unique text up to 128 characters. A retry with the same key and the same body within 24 hours returns the first answer (with the header Idempotent-Replayed: true) instead of doing the work twice. The same key with another body answers 409 idempotency_conflict. | Body fields (JSON) | Field | Type | Required | Description | | --- | --- | --- | --- | | `credits` | integer | yes | Credits in the pack: 500, 5000, 25000 or 100000. One of 500, 5000, 25000, 100000. | | `currency` | string | no | usd (default) or eur. One of usd, eur. | Example request ```bash curl -X POST "https://app.argorant.com/api/v1/credits/quote" \ -H "Authorization: Bearer $ARGORANT_API_KEY" \ -H "Content-Type: application/json" \ -d '{"credits":5000,"currency":"usd"}' ``` Example answer (200) ```json { "quote_id": "2f8a1b3c-4d5e-4f70-8192-a3b4c5d6e7f8", "credits": 5000, "currency": "usd", "amount_cents": 6900, "price": "$69.00", "valid_for_days": 365, "expires_at": "2026-10-08T12:00:00+00:00", "summary": "5,000 credits for $69.00, paid once, no subscription. They stay valid for 365 days and work for contacts (1 credit each), email checks (0.5 credit) and phone numbers (10 credits).", "payment": { "saved_card": { "usable": false, "card": null, "charge_before": null, "reason": "The account owner has not allowed AI assistants to buy credits with the saved card. The owner can switch it on in Settings > Billing.", "code": "not_opted_in" }, "summary": "The purchase returns a payment link the user pays themselves. Nothing is charged before that payment." }, "next_step": "Show this quote to the user and buy only after their explicit yes: POST /api/v1/credits/purchases with quote_id, confirmed=true and the user's own words in user_confirmation. You get a payment link to give to the user." } ``` It can answer with these errors (status and code): 401 unauthorized; 403 scope_missing; 409 idempotency_conflict; 422 validation_error; 429 rate_limited; 503 unavailable. ### List credit purchases `GET /api/v1/credits/purchases` Credit purchases made through the API and AI agents, newest first. A payment link shows paid once the user paid it, and expired when it ran out unpaid. | Cost | What it does | Key scopes | | --- | --- | --- | | Free | Reads only | argorant:read_counts | Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `limit` | query | integer | no | Rows per page, 1 to 100 (default 25). | | `cursor` | query | string | no | The next_cursor of the previous page. Leave out for the first page. | | `offset` | query | integer | no | Rows to skip, as an alternative to cursor. | Example request ```bash curl -X GET "https://app.argorant.com/api/v1/credits/purchases?limit=25" \ -H "Authorization: Bearer $ARGORANT_API_KEY" ``` Example answer (200) ```json { "purchases": [ { "purchase_id": "2f8a1b3c-4d5e-4f70-8192-a3b4c5d6e7f8", "status": "paid", "paid_with": "saved_card", "credits": 5000, "amount_cents": 6900, "currency": "usd", "price": "$69.00", "created_at": "2026-10-07T12:01:00+00:00", "updated_at": "2026-10-07T12:01:03+00:00", "card": "card ending 4242", "credits_added": 5000, "checkout_url": null, "message": "Charged $69.00 to the saved card ending 4242. 5,000 credits were added to the account and stay valid for 365 days." } ], "total": 1, "limit": 25, "offset": 0, "next_cursor": null, "has_more": false } ``` It can answer with these errors (status and code): 401 unauthorized; 403 scope_missing; 422 validation_error; 429 rate_limited. ### Buy a credit pack `POST /api/v1/credits/purchases` Buys exactly what a quote showed. `confirmed: true` states that the person who pays said yes to that quote; pass their own words in `user_confirmation`. Every purchase records who confirmed it, when, through which key or connection, the amount and the quote. Buy with the same key or connection that asked for the quote; a quote from another one is refused with 409 quote_other_session. With `pay_with: auto` the saved card the owner allowed in the app is charged right away when the amount fits the owner's monthly limit and the workspace's limits; the credits are added at once and a receipt is emailed. Otherwise you get `checkout_url`, a payment page the person pays themselves; the credits arrive with that payment. The quote id makes this safe to retry: the same quote is never charged twice, and a repeat returns the first answer with `replayed: true`. | Cost | What it does | Key scopes | | --- | --- | --- | | The pack price, charged only after the person who pays confirmed the quote | charges money | argorant:manage_lists | Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `Idempotency-Key` | header | string | no | Any unique text up to 128 characters. A retry with the same key and the same body within 24 hours returns the first answer (with the header Idempotent-Replayed: true) instead of doing the work twice. The same key with another body answers 409 idempotency_conflict. | Body fields (JSON) | Field | Type | Required | Description | | --- | --- | --- | --- | | `quote_id` | string | yes | The quote the person said yes to. | | `confirmed` | boolean | yes | true: the person who pays saw the quote and said yes. | | `pay_with` | string | no | auto: the saved card when allowed, else a payment link. link: always a payment link. One of auto, link. | | `user_confirmation` | string | no | The person's own words that said yes to the quote, quoted exactly (up to 1,000 characters). Recorded with the purchase; without it the record says confirmed=true. | | `price_shown_cents` | integer | no | The price you showed the person, in cents of the quote's currency. Recorded with the purchase. A price that differs from the quote is refused with 409 price_mismatch. | | `tool_call_id` | string | no | The id of your tool call that carries this yes, if your app has one. Recorded with the purchase. | Example request ```bash curl -X POST "https://app.argorant.com/api/v1/credits/purchases" \ -H "Authorization: Bearer $ARGORANT_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{"quote_id":"2f8a1b3c-4d5e-4f70-8192-a3b4c5d6e7f8","confirmed":true,"pay_with":"auto","user_confirmation":"Yes, buy the 5,000 credits for $69","price_shown_cents":6900}' ``` Example answer (201) ```json { "purchase_id": "2f8a1b3c-4d5e-4f70-8192-a3b4c5d6e7f8", "status": "awaiting_payment", "paid_with": "payment_link", "checkout_url": "https://checkout.example.com/pay/cs_live_a1B2c3", "credits": 5000, "amount_cents": 6900, "currency": "usd", "message": "Not charged to the saved card: The account owner has not allowed AI assistants to buy credits with the saved card. The owner can switch it on in Settings > Billing. Send this payment link to the user. 5,000 credits for $69.00 are added as soon as they pay. Nothing is charged before that.", "saved_card": { "used": false, "code": "not_opted_in", "reason": "The account owner has not allowed AI assistants to buy credits with the saved card. The owner can switch it on in Settings > Billing." } } ``` It can answer with these errors (status and code): 400 confirmation_required; 401 unauthorized; 403 scope_missing; 404 quote_not_found; 409 charge_in_progress, idempotency_conflict; 410 quote_expired; 422 validation_error; 429 rate_limited. ### Get a credit purchase `GET /api/v1/credits/purchases/{purchase_id}` One purchase, with whether it is paid, waiting for payment, not charged or expired, and how many credits it added. | Cost | What it does | Key scopes | | --- | --- | --- | | Free | Reads only | argorant:read_counts | Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `purchase_id` | path | string | yes | The purchase id (the same as its quote id). | Example request ```bash curl -X GET "https://app.argorant.com/api/v1/credits/purchases/2f8a1b3c-4d5e-4f70-8192-a3b4c5d6e7f8" \ -H "Authorization: Bearer $ARGORANT_API_KEY" ``` Example answer (200) ```json { "purchase_id": "2f8a1b3c-4d5e-4f70-8192-a3b4c5d6e7f8", "status": "paid", "paid_with": "payment_link", "credits": 5000, "amount_cents": 6900, "currency": "usd", "price": "$69.00", "created_at": "2026-10-07T12:01:00+00:00", "updated_at": "2026-10-07T12:04:10+00:00", "checkout_url": null, "message": "Paid. 5,000 credits were added to the account." } ``` It can answer with these errors (status and code): 401 unauthorized; 403 scope_missing; 404 not_found; 429 rate_limited. ### Industries `GET /api/v1/lookups/industries` Industry names with how many contacts carry each. Type plain words (saas) and get the exact names to use in the industries filter. Free. | Cost | What it does | Key scopes | | --- | --- | --- | | Free | Reads only | argorant:read_counts | Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `q` | query | string | no | The start of a word or a few words. | | `limit` | query | integer | no | How many, 1 to 100 (default 25). | Example request ```bash curl -X GET "https://app.argorant.com/api/v1/lookups/industries?q=soft" \ -H "Authorization: Bearer $ARGORANT_API_KEY" ``` Example answer (200) ```json { "suggestions": [ { "value": "Software Development", "label": "Software Development", "count": 18402551 }, { "value": "IT Services and IT Consulting", "label": "IT Services and IT Consulting", "count": 11204889 } ], "total": 2, "limit": 25, "offset": 0, "next_cursor": null, "has_more": false } ``` It can answer with these errors (status and code): 401 unauthorized; 403 scope_missing; 422 validation_error; 429 rate_limited. ### Countries `GET /api/v1/lookups/countries` Country names with how many contacts live there. Germany and DE land on the same country. Free. | Cost | What it does | Key scopes | | --- | --- | --- | | Free | Reads only | argorant:read_counts | Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `q` | query | string | no | The start of a word or a few words. | | `limit` | query | integer | no | How many, 1 to 100 (default 25). | Example request ```bash curl -X GET "https://app.argorant.com/api/v1/lookups/countries?q=ger" \ -H "Authorization: Bearer $ARGORANT_API_KEY" ``` Example answer (200) ```json { "suggestions": [ { "value": "Germany", "label": "Germany", "count": 2516622 } ], "total": 1, "limit": 25, "offset": 0, "next_cursor": null, "has_more": false } ``` It can answer with these errors (status and code): 401 unauthorized; 403 scope_missing; 422 validation_error; 429 rate_limited. ### Keywords `GET /api/v1/lookups/keywords` Keywords such as technologies, business models and niche tags, with how many contacts carry each. Keywords reach niches that have no industry of their own. Free. | Cost | What it does | Key scopes | | --- | --- | --- | | Free | Reads only | argorant:read_counts | Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `q` | query | string | no | The start of a word or a few words. | | `limit` | query | integer | no | How many, 1 to 100 (default 25). | Example request ```bash curl -X GET "https://app.argorant.com/api/v1/lookups/keywords?q=buyout" \ -H "Authorization: Bearer $ARGORANT_API_KEY" ``` Example answer (200) ```json { "suggestions": [ { "value": "Buyout/LBO", "count": 38211 }, { "value": "Growth Equity", "count": 21044 } ], "total": 2, "limit": 25, "offset": 0, "next_cursor": null, "has_more": false } ``` It can answer with these errors (status and code): 401 unauthorized; 403 scope_missing; 422 validation_error; 429 rate_limited. ### Technologies `GET /api/v1/lookups/technologies` Technologies companies use, with how many contacts work at those companies. Free. | Cost | What it does | Key scopes | | --- | --- | --- | | Free | Reads only | argorant:read_counts | Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `q` | query | string | no | The start of a word or a few words. | | `limit` | query | integer | no | How many, 1 to 100 (default 25). | Example request ```bash curl -X GET "https://app.argorant.com/api/v1/lookups/technologies?q=shopi" \ -H "Authorization: Bearer $ARGORANT_API_KEY" ``` Example answer (200) ```json { "suggestions": [ { "value": "Shopify", "count": 1840211 }, { "value": "Shopify Plus", "count": 210448 } ], "total": 2, "limit": 25, "offset": 0, "next_cursor": null, "has_more": false } ``` It can answer with these errors (status and code): 401 unauthorized; 403 scope_missing; 422 validation_error; 429 rate_limited. ### Job titles `GET /api/v1/lookups/titles` Job titles as people write them, with how many contacts hold each. Free. | Cost | What it does | Key scopes | | --- | --- | --- | | Free | Reads only | argorant:read_counts | Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `q` | query | string | no | The start of a word or a few words. | | `limit` | query | integer | no | How many, 1 to 50 (default 20). | Example request ```bash curl -X GET "https://app.argorant.com/api/v1/lookups/titles?q=head%20of" \ -H "Authorization: Bearer $ARGORANT_API_KEY" ``` Example answer (200) ```json { "suggestions": [ { "value": "Head of Sales", "count": 412904 }, { "value": "Head of Marketing", "count": 388140 } ], "total": 2, "limit": 25, "offset": 0, "next_cursor": null, "has_more": false } ``` It can answer with these errors (status and code): 401 unauthorized; 403 scope_missing; 422 validation_error; 429 rate_limited. ### Count people `GET /api/v1/people/count` How many people match your filters. Free. Start every search here to size the market before you preview or spend. | Cost | What it does | Key scopes | | --- | --- | --- | | Free | Reads only | argorant:read_counts | Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `q` | query | string | no | Plain text across name, title, company and description. A request like "software companies selling to restaurants" is understood as the vendors, not the restaurants. | | `title` | query | string | no | Job title. Knows abbreviations (CFO matches Chief Financial Officer). Comma means or. | | `exclude_title` | query | string | no | Leave out people with these titles. Comma means or. | | `seniority` | query | string | no | Comma-separated seniority levels. One of Owner, Founder, Partner, C-Level, VP, Director, Manager, Senior, Entry, Intern. | | `departments` | query | string | no | Comma-separated departments. One of Sales, Marketing, Engineering, Product, Finance, Human Resources, Operations, Legal, Customer Success, IT, Design, Data, Research, Executive. | | `industries` | query | string | no | Pipe-separated industries from GET /api/v1/lookups/industries. | | `industry` | query | string | no | One industry in plain words; industries is more exact. | | `keywords` | query | string | no | Comma-separated words that describe what the company does, such as fintech or freight forwarding. They match the company's name, tags, industry and description. They do not match a person's own skills unless keyword_scope is people or any. The widest filter for niches without their own industry. | | `technologies` | query | string | no | Pipe-separated technologies the company uses, from GET /api/v1/lookups/technologies. | | `employee_range` | query | string | no | Comma-separated company sizes. One of 1-10, 11-50, 51-200, 201-500, 501-1000, 1001-5000, 5001-10000, 10000+, unknown. | | `company_name` | query | string | no | Company name, matched as written (Deutsche Bank finds Deutsche Bank AG). Several companies: join the names with \|, for example Stripe\|Notion. | | `company_domain` | query | string | no | Company website domains. Comma means or. | | `country` | query | string | no | Comma-separated countries or regions (Europe, DACH, Nordics, APAC, LATAM). Names from GET /api/v1/lookups/countries. Regions can overlap. Egypt is in both Middle East and Africa, Mexico is in both North America and LATAM, and Turkey counts as Middle East, not Europe. A person is counted once, even when several of the regions you name include their country. | | `state` | query | string | no | States or provinces, by name or code. Comma means or. | | `city` | query | string | no | Cities. Comma means or. | | `sells_to` | query | string | no | Who the company sells to, for example restaurants or dentists. | | `company_category` | query | string | no | What the company itself is, used with sells_to. One of software, payments, fintech, formation, association, marketplace, investors. | | `has_phone` | query | boolean | no | Only people with a phone number on record. | | `has_linkedin` | query | boolean | no | Only people with a profile URL. | | `exclude_keywords` | query | string | no | Leave out people that keywords would find for these words. Same matching and the same keyword_scope as keywords. Comma means or. | | `keyword_scope` | query | string | no | company (default): only what the company does, that is its name, tags, industry and description. people: only the person's own skills and profile; use it when the user wants people who have a skill themselves, such as people who know Python. any: both, plus job titles. One of company, people, any. | | `title_match` | query | string | no | words (default): every word must appear as a whole word, so Data does not match Database. exact: the whole job title must be one of the values, ignoring case, so CEO does not match Founder & CEO. contains: the text may appear anywhere, also inside a word; slower, for special cases. One of words, exact, contains. | | `exclude_title_match` | query | string | no | Like title_match, for exclude_title only. When it is not set, title_match is used. One of words, exact, contains. | | `exclude_seniority` | query | string | no | Leave out these seniority levels. Comma means or. One of Owner, Founder, Partner, C-Level, VP, Director, Manager, Senior, Entry, Intern. | | `exclude_departments` | query | string | no | Leave out these departments. Comma means or. One of Sales, Marketing, Engineering, Product, Finance, Human Resources, Operations, Legal, Customer Success, IT, Design, Data, Research, Executive. | | `exclude_industries` | query | string | no | Leave out these industries (pipe-separated, like industries). | | `exclude_industry` | query | string | no | Leave out industries in plain words, like industry. Comma means or. | | `exclude_company_domain` | query | string | no | Leave out people at these company website domains. Comma means or. | | `exclude_country` | query | string | no | Leave out these countries or regions (Europe, DACH, Nordics, APAC, LATAM). Comma means or. | | `exclude_state` | query | string | no | Leave out these states or provinces, by name or code. Comma means or. | | `exclude_city` | query | string | no | Leave out these cities. Comma means or. | | `employees_min` | query | string | no | Smallest number of employees, such as 50 and 500. A company counts when its size range overlaps yours. Accepts 100 or 1k. | | `employees_max` | query | string | no | Largest number of employees (same overlap rule). | | `revenue_band` | query | string | no | Yearly company revenue in US dollars, as bands. A comma means any of them. One of 0-1m, 1m-10m, 10m-50m, 50m-100m, 100m-250m, 250m-500m, 500m-1b, 1b-10b, 10b+. | | `revenue_min` | query | string | no | Smallest yearly revenue in US dollars; a company counts when its revenue range overlaps yours. Accepts 250k, 1.5M or 2B. | | `revenue_max` | query | string | no | Largest yearly revenue in US dollars (same overlap rule). | | `business_email_only` | query | boolean | no | Only people whose email is at their company's own domain. Off unless you set it, so private addresses are left out only on request. When it is on, the answer says so under applied_filters. | | `exclude_assistants` | query | boolean | no | On by default. A job title search leaves out assistant titles such as assistant to, executive assistant or personal assistant. Set it to false to keep them. The answer lists what it left out under applied_defaults, and a saved list keeps the setting. | Example request ```bash curl -X GET "https://app.argorant.com/api/v1/people/count?q=head%20of%20growth&title=CFO%2CVP%20Finance&exclude_title=assistant%2Cintern&seniority=C-Level%2CVP&departments=Finance&industries=Software%20Development%7CFinancial%20Services&industry=fintech&keywords=solar%2Crenewable&technologies=Shopify%7CKlaviyo&employee_range=11-50%2C51-200&company_name=Stripe&company_domain=stripe.com&country=Germany%2CAustria&state=Bavaria&city=Munich&sells_to=restaurants&exclude_keywords=staffing%2Crecruiting&exclude_seniority=Intern%2CEntry&exclude_departments=Human%20Resources&exclude_industries=Staffing%20and%20Recruiting&exclude_industry=staffing&exclude_company_domain=competitor.com&exclude_country=Switzerland&exclude_state=CA%2CNY&exclude_city=Berlin&employees_min=50&employees_max=500&revenue_band=10m-50m&revenue_min=1M&revenue_max=50M" \ -H "Authorization: Bearer $ARGORANT_API_KEY" ``` Example answer (200) ```json { "count": 18432 } ``` It can answer with these errors (status and code): 401 unauthorized; 403 scope_missing; 422 validation_error; 429 daily_limit_reached, rate_limited. ### Search filters `GET /api/v1/people/filters` Every people filter the API, the app, the Claude connector and the CLI share: names, what each one does, the allowed values for dropdowns, which filters can leave people out, and which are ready right now. Free. Include and exclude work together, also for the same kind of filter: an exclude filter leaves out everyone its include filter would find for the same values. | Cost | What it does | Key scopes | | --- | --- | --- | | Free | Reads only | argorant:read_counts | Example request ```bash curl -X GET "https://app.argorant.com/api/v1/people/filters" \ -H "Authorization: Bearer $ARGORANT_API_KEY" ``` Example answer (200) ```json { "version": "2026-10-12.1", "filters": [ { "key": "title", "label": "Job titles", "kind": "text_list", "include": "title", "exclude": "exclude_title", "mode": "title_match", "ready": true }, { "key": "seniority", "label": "Seniority", "kind": "enum_list", "include": "seniority", "exclude": "exclude_seniority", "values": [ { "value": "C-Level", "label": "C-Level" }, { "value": "VP", "label": "VP" } ], "ready": true }, { "key": "gender", "label": "Gender", "kind": "enum_list", "include": "gender", "exclude": null, "ready": false, "reason": "Gender is still being added to every record." } ], "modes": { "title_match": { "default": "words", "values": [ { "value": "words", "label": "Whole words" }, { "value": "exact", "label": "Exact role" }, { "value": "contains", "label": "Contains the text" } ] }, "keyword_scope": { "default": "company", "values": [ { "value": "company", "label": "What the company does" }, { "value": "people", "label": "P ... ``` It can answer with these errors (status and code): 401 unauthorized; 403 scope_missing; 429 rate_limited. ### Search people `GET /api/v1/people/search` A preview of the people who match: role, seniority, company, place and industry, with names cut to initials and no contact details. Free. Use it to check that the filters find the right people, then reveal, save a list or export. A page holds up to 10 people for customer keys, and on a plan there is no daily limit on preview rows; during the trial an account can preview 1,000 rows a day through an AI assistant and 500 through an API key (all its keys together). To work with more people, save a list or start an export. Each row carries the record_id you can reveal, add to a list or ask phone numbers for. | Cost | What it does | Key scopes | | --- | --- | --- | | Free | Reads only | argorant:search_segments | Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `q` | query | string | no | Plain text across name, title, company and description. A request like "software companies selling to restaurants" is understood as the vendors, not the restaurants. | | `title` | query | string | no | Job title. Knows abbreviations (CFO matches Chief Financial Officer). Comma means or. | | `exclude_title` | query | string | no | Leave out people with these titles. Comma means or. | | `seniority` | query | string | no | Comma-separated seniority levels. One of Owner, Founder, Partner, C-Level, VP, Director, Manager, Senior, Entry, Intern. | | `departments` | query | string | no | Comma-separated departments. One of Sales, Marketing, Engineering, Product, Finance, Human Resources, Operations, Legal, Customer Success, IT, Design, Data, Research, Executive. | | `industries` | query | string | no | Pipe-separated industries from GET /api/v1/lookups/industries. | | `industry` | query | string | no | One industry in plain words; industries is more exact. | | `keywords` | query | string | no | Comma-separated words that describe what the company does, such as fintech or freight forwarding. They match the company's name, tags, industry and description. They do not match a person's own skills unless keyword_scope is people or any. The widest filter for niches without their own industry. | | `technologies` | query | string | no | Pipe-separated technologies the company uses, from GET /api/v1/lookups/technologies. | | `employee_range` | query | string | no | Comma-separated company sizes. One of 1-10, 11-50, 51-200, 201-500, 501-1000, 1001-5000, 5001-10000, 10000+, unknown. | | `company_name` | query | string | no | Company name, matched as written (Deutsche Bank finds Deutsche Bank AG). Several companies: join the names with \|, for example Stripe\|Notion. | | `company_domain` | query | string | no | Company website domains. Comma means or. | | `country` | query | string | no | Comma-separated countries or regions (Europe, DACH, Nordics, APAC, LATAM). Names from GET /api/v1/lookups/countries. Regions can overlap. Egypt is in both Middle East and Africa, Mexico is in both North America and LATAM, and Turkey counts as Middle East, not Europe. A person is counted once, even when several of the regions you name include their country. | | `state` | query | string | no | States or provinces, by name or code. Comma means or. | | `city` | query | string | no | Cities. Comma means or. | | `sells_to` | query | string | no | Who the company sells to, for example restaurants or dentists. | | `company_category` | query | string | no | What the company itself is, used with sells_to. One of software, payments, fintech, formation, association, marketplace, investors. | | `has_phone` | query | boolean | no | Only people with a phone number on record. | | `has_linkedin` | query | boolean | no | Only people with a profile URL. | | `exclude_keywords` | query | string | no | Leave out people that keywords would find for these words. Same matching and the same keyword_scope as keywords. Comma means or. | | `keyword_scope` | query | string | no | company (default): only what the company does, that is its name, tags, industry and description. people: only the person's own skills and profile; use it when the user wants people who have a skill themselves, such as people who know Python. any: both, plus job titles. One of company, people, any. | | `title_match` | query | string | no | words (default): every word must appear as a whole word, so Data does not match Database. exact: the whole job title must be one of the values, ignoring case, so CEO does not match Founder & CEO. contains: the text may appear anywhere, also inside a word; slower, for special cases. One of words, exact, contains. | | `exclude_title_match` | query | string | no | Like title_match, for exclude_title only. When it is not set, title_match is used. One of words, exact, contains. | | `exclude_seniority` | query | string | no | Leave out these seniority levels. Comma means or. One of Owner, Founder, Partner, C-Level, VP, Director, Manager, Senior, Entry, Intern. | | `exclude_departments` | query | string | no | Leave out these departments. Comma means or. One of Sales, Marketing, Engineering, Product, Finance, Human Resources, Operations, Legal, Customer Success, IT, Design, Data, Research, Executive. | | `exclude_industries` | query | string | no | Leave out these industries (pipe-separated, like industries). | | `exclude_industry` | query | string | no | Leave out industries in plain words, like industry. Comma means or. | | `exclude_company_domain` | query | string | no | Leave out people at these company website domains. Comma means or. | | `exclude_country` | query | string | no | Leave out these countries or regions (Europe, DACH, Nordics, APAC, LATAM). Comma means or. | | `exclude_state` | query | string | no | Leave out these states or provinces, by name or code. Comma means or. | | `exclude_city` | query | string | no | Leave out these cities. Comma means or. | | `employees_min` | query | string | no | Smallest number of employees, such as 50 and 500. A company counts when its size range overlaps yours. Accepts 100 or 1k. | | `employees_max` | query | string | no | Largest number of employees (same overlap rule). | | `revenue_band` | query | string | no | Yearly company revenue in US dollars, as bands. A comma means any of them. One of 0-1m, 1m-10m, 10m-50m, 50m-100m, 100m-250m, 250m-500m, 500m-1b, 1b-10b, 10b+. | | `revenue_min` | query | string | no | Smallest yearly revenue in US dollars; a company counts when its revenue range overlaps yours. Accepts 250k, 1.5M or 2B. | | `revenue_max` | query | string | no | Largest yearly revenue in US dollars (same overlap rule). | | `business_email_only` | query | boolean | no | Only people whose email is at their company's own domain. Off unless you set it, so private addresses are left out only on request. When it is on, the answer says so under applied_filters. | | `exclude_assistants` | query | boolean | no | On by default. A job title search leaves out assistant titles such as assistant to, executive assistant or personal assistant. Set it to false to keep them. The answer lists what it left out under applied_defaults, and a saved list keeps the setting. | | `limit` | query | integer | no | Rows per page, 1 to 100 (default 10). | | `cursor` | query | string | no | The next_cursor of the previous page. Leave out for the first page. | | `offset` | query | integer | no | Rows to skip, as an alternative to cursor. | Example request ```bash curl -X GET "https://app.argorant.com/api/v1/people/search?q=head%20of%20growth&title=CFO%2CVP%20Finance&exclude_title=assistant%2Cintern&seniority=C-Level%2CVP&departments=Finance&industries=Software%20Development%7CFinancial%20Services&industry=fintech&keywords=solar%2Crenewable&technologies=Shopify%7CKlaviyo&employee_range=11-50%2C51-200&company_name=Stripe&company_domain=stripe.com&country=Germany%2CAustria&state=Bavaria&city=Munich&sells_to=restaurants&exclude_keywords=staffing%2Crecruiting&exclude_seniority=Intern%2CEntry&exclude_departments=Human%20Resources&exclude_industries=Staffing%20and%20Recruiting&exclude_industry=staffing&exclude_company_domain=competitor.com&exclude_country=Switzerland&exclude_state=CA%2CNY&exclude_city=Berlin&employees_min=50&employees_max=500&revenue_band=10m-50m&revenue_min=1M&revenue_max=50M&limit=10" \ -H "Authorization: Bearer $ARGORANT_API_KEY" ``` Example answer (200) ```json { "people": [ { "record_id": "p_8d4ba3d46cc885007c38e437", "preview": "A* S", "title": "VP of Sales", "seniority": "VP", "departments": [ "Sales" ], "company": "Evenito AG", "company_normalized": "Evenito", "company_domain": "evenito.com", "city": "Zurich", "state": null, "country": "Switzerland", "industry": "Software Development", "industries": [ "Software", "Software Development" ] } ], "total": 1843, "limit": 10, "offset": 0, "next_cursor": "bzoxMA", "has_more": true, "note": "Names and contact details are masked. Reveal or export to get emails; counts and searches are free." } ``` It can answer with these errors (status and code): 401 unauthorized; 403 scope_missing; 422 validation_error; 429 daily_limit_reached, rate_limited. ### Reveal people `POST /api/v1/people/reveal` Full details for people, with name, title, company, work email, profile URL and place. Send `record_ids` from a search (up to 25), or the same filters as search to take the next people who match. Every email is checked right before you get it; only people whose email passes are returned and charged. A person you revealed before is free to reveal again. Ask the user before you spend: show the count and the price first. A key can reveal 100 people a day. For bigger numbers use a saved list and an export, or add the list to a campaign. | Cost | What it does | Key scopes | | --- | --- | --- | | 1 credit per contact whose email passes the check; contacts that fail are left out and cost nothing | spends credits | argorant:unlock_contacts | Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `Idempotency-Key` | header | string | no | Any unique text up to 128 characters. A retry with the same key and the same body within 24 hours returns the first answer (with the header Idempotent-Replayed: true) instead of doing the work twice. The same key with another body answers 409 idempotency_conflict. | Body fields (JSON) | Field | Type | Required | Description | | --- | --- | --- | --- | | `record_ids` | array of string | no | Up to 25 record ids from a search. Leave out to reveal by filters. | | `q` | string | no | Plain text across name, title, company and description. A request like "software companies selling to restaurants" is understood as the vendors, not the restaurants. | | `title` | string | no | Job title. Knows abbreviations (CFO matches Chief Financial Officer). Comma means or. | | `exclude_title` | string | no | Leave out people with these titles. Comma means or. | | `seniority` | string | no | Comma-separated seniority levels. One of Owner, Founder, Partner, C-Level, VP, Director, Manager, Senior, Entry, Intern. | | `departments` | string | no | Comma-separated departments. One of Sales, Marketing, Engineering, Product, Finance, Human Resources, Operations, Legal, Customer Success, IT, Design, Data, Research, Executive. | | `industries` | string | no | Pipe-separated industries from GET /api/v1/lookups/industries. | | `industry` | string | no | One industry in plain words; industries is more exact. | | `keywords` | string | no | Comma-separated words that describe what the company does, such as fintech or freight forwarding. They match the company's name, tags, industry and description. They do not match a person's own skills unless keyword_scope is people or any. The widest filter for niches without their own industry. | | `technologies` | string | no | Pipe-separated technologies the company uses, from GET /api/v1/lookups/technologies. | | `employee_range` | string | no | Comma-separated company sizes. One of 1-10, 11-50, 51-200, 201-500, 501-1000, 1001-5000, 5001-10000, 10000+, unknown. | | `company_name` | string | no | Company name, matched as written (Deutsche Bank finds Deutsche Bank AG). Several companies: join the names with \|, for example Stripe\|Notion. | | `company_domain` | string | no | Company website domains. Comma means or. | | `country` | string | no | Comma-separated countries or regions (Europe, DACH, Nordics, APAC, LATAM). Names from GET /api/v1/lookups/countries. Regions can overlap. Egypt is in both Middle East and Africa, Mexico is in both North America and LATAM, and Turkey counts as Middle East, not Europe. A person is counted once, even when several of the regions you name include their country. | | `state` | string | no | States or provinces, by name or code. Comma means or. | | `city` | string | no | Cities. Comma means or. | | `sells_to` | string | no | Who the company sells to, for example restaurants or dentists. | | `company_category` | string | no | What the company itself is, used with sells_to. One of software, payments, fintech, formation, association, marketplace, investors. | | `has_phone` | boolean | no | Only people with a phone number on record. | | `has_linkedin` | boolean | no | Only people with a profile URL. | | `exclude_keywords` | string | no | Leave out people that keywords would find for these words. Same matching and the same keyword_scope as keywords. Comma means or. | | `keyword_scope` | string | no | company (default): only what the company does, that is its name, tags, industry and description. people: only the person's own skills and profile; use it when the user wants people who have a skill themselves, such as people who know Python. any: both, plus job titles. One of company, people, any. | | `title_match` | string | no | words (default): every word must appear as a whole word, so Data does not match Database. exact: the whole job title must be one of the values, ignoring case, so CEO does not match Founder & CEO. contains: the text may appear anywhere, also inside a word; slower, for special cases. One of words, exact, contains. | | `exclude_title_match` | string | no | Like title_match, for exclude_title only. When it is not set, title_match is used. One of words, exact, contains. | | `exclude_seniority` | string | no | Leave out these seniority levels. Comma means or. One of Owner, Founder, Partner, C-Level, VP, Director, Manager, Senior, Entry, Intern. | | `exclude_departments` | string | no | Leave out these departments. Comma means or. One of Sales, Marketing, Engineering, Product, Finance, Human Resources, Operations, Legal, Customer Success, IT, Design, Data, Research, Executive. | | `exclude_industries` | string | no | Leave out these industries (pipe-separated, like industries). | | `exclude_industry` | string | no | Leave out industries in plain words, like industry. Comma means or. | | `exclude_company_domain` | string | no | Leave out people at these company website domains. Comma means or. | | `exclude_country` | string | no | Leave out these countries or regions (Europe, DACH, Nordics, APAC, LATAM). Comma means or. | | `exclude_state` | string | no | Leave out these states or provinces, by name or code. Comma means or. | | `exclude_city` | string | no | Leave out these cities. Comma means or. | | `employees_min` | string | no | Smallest number of employees, such as 50 and 500. A company counts when its size range overlaps yours. Accepts 100 or 1k. | | `employees_max` | string | no | Largest number of employees (same overlap rule). | | `revenue_band` | string | no | Yearly company revenue in US dollars, as bands. A comma means any of them. One of 0-1m, 1m-10m, 10m-50m, 50m-100m, 100m-250m, 250m-500m, 500m-1b, 1b-10b, 10b+. | | `revenue_min` | string | no | Smallest yearly revenue in US dollars; a company counts when its revenue range overlaps yours. Accepts 250k, 1.5M or 2B. | | `revenue_max` | string | no | Largest yearly revenue in US dollars (same overlap rule). | | `limit` | integer | no | How many people when revealing by filters, 1 to 25 per call (default 10). | | `grade` | string | no | valid: only confirmed addresses. valid_plus_catchall: also addresses at domains that accept every email. Default: both. One of valid, valid_plus_catchall. | Example request ```bash curl -X POST "https://app.argorant.com/api/v1/people/reveal" \ -H "Authorization: Bearer $ARGORANT_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{"title":"CFO","country":"Germany","employee_range":"51-200","limit":10}' ``` Example answer (200) ```json { "people": [ { "record_id": "p_8d4ba3d46cc885007c38e437", "first_name": "Alex", "last_name": "Schneider", "full_name": "Alex Schneider", "title": "VP of Sales", "seniority": "VP", "departments": [ "Sales" ], "company": "Evenito AG", "company_normalized": "Evenito", "company_domain": "evenito.com", "email": "alex@evenito.com", "email_status": "valid", "linkedin_url": "https://www.linkedin.com/in/alexschneider", "city": "Zurich", "state": null, "country": "Switzerland", "industry": "Software Development", "industries": [ "Software", "Software Development" ] } ], "returned": 10, "credits_charged": 9, "already_unlocked": 1, "total_matches": 1843, "not_revealed": [], "note": "Every email was checked live. You pay 1 credit per person you had not unlocked before; invalid emails are never returned or charged." } ``` It can answer with these errors (status and code): 401 unauthorized; 402 insufficient_credits; 403 scope_missing, permission_missing; 409 idempotency_conflict; 422 validation_error; 429 daily_limit_reached, rate_limited. ### Get phone numbers `POST /api/v1/people/phones` Add the direct dial or mobile number of up to 100 people you already found with search, reveal or enrich. Phone numbers are never included unless you ask for them. Each number that comes back costs 10 credits. People without a number cost nothing, and numbers your account already unlocked are free, whether that was in the app, the API, the command line or an AI connector. Phone numbers come with the Pro plan and higher. Every result says whether a number was returned and what it cost. phone_status is returned (charged), already_unlocked (free), none_found (free), not_found (free), not_in_plan, not_enough_credits or daily_limit_reached. When the credits run out part way, the call still returns the numbers it could pay for and says where it stopped (stopped). If not a single number could be paid for, the answer is 402 insufficient_credits. | Cost | What it does | Key scopes | | --- | --- | --- | | 10 credits per phone number returned; no number, no charge; numbers you already unlocked are free | spends credits | argorant:unlock_contacts | Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `Idempotency-Key` | header | string | no | Any unique text up to 128 characters. A retry with the same key and the same body within 24 hours returns the first answer (with the header Idempotent-Replayed: true) instead of doing the work twice. The same key with another body answers 409 idempotency_conflict. | Body fields (JSON) | Field | Type | Required | Description | | --- | --- | --- | --- | | `record_ids` | array of string | yes | Up to 100 person ids (record_id from search, reveal or enrich). | Example request ```bash curl -X POST "https://app.argorant.com/api/v1/people/phones" \ -H "Authorization: Bearer $ARGORANT_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{"record_ids":["p_8d4ba3d46cc885007c38e437","p_1f0c2a9e77b3d4410e8a5c21","p_77aa01b2c3d4e5f60718293a"]}' ``` Example answer (200) ```json { "price_per_phone": 10, "charged_only_when_found": true, "requested": 3, "phones_returned": 2, "phones_charged": 1, "credits_charged": 10, "stopped": null, "summary": "2 phone numbers returned. 1 is new for 10 credits, and 1 you already had for free. 1 person has no phone number on record. That costs nothing.", "results": [ { "record_id": "p_8d4ba3d46cc885007c38e437", "full_name": "Alex Schneider", "phone": "+41445551234", "additional_phones": [], "phone_status": "returned", "credits_charged": 10 }, { "record_id": "p_1f0c2a9e77b3d4410e8a5c21", "full_name": "Maria Lenz", "phone": "+4930555987", "additional_phones": [], "phone_status": "already_unlocked", "credits_charged": 0 }, { "record_id": "p_77aa01b2c3d4e5f60718293a", "full_name": "Tom Berg", "phone": null, "additional_phones": [], "phone_status": "none_found", "credits_charged": 0 } ] } ``` It can answer with these errors (status and code): 401 unauthorized; 402 phones_not_in_plan, insufficient_credits; 403 scope_missing; 409 idempotency_conflict; 422 validation_error; 429 daily_limit_reached, rate_limited. ### Phone number price and balance `GET /api/v1/people/phones/pricing` Check the price of a phone number, whether your plan includes phone numbers, and your credit balance before you spend anything. Free. | Cost | What it does | Key scopes | | --- | --- | --- | | Free | Reads only | argorant:unlock_contacts | Example request ```bash curl -X GET "https://app.argorant.com/api/v1/people/phones/pricing" \ -H "Authorization: Bearer $ARGORANT_API_KEY" ``` Example answer (200) ```json { "price_per_phone": 10, "charged_only_when_found": true, "already_unlocked_free": true, "plan_includes_phones": true, "billing_exempt": false, "credits_available": 23140, "summary": "Phone numbers cost 10 credits each, only when a number is found. Numbers this account already unlocked are free." } ``` It can answer with these errors (status and code): 401 unauthorized; 403 scope_missing; 429 rate_limited. ### Count companies `GET /api/v1/companies/count` How many companies match your filters. Free. | Cost | What it does | Key scopes | | --- | --- | --- | | Free | Reads only | argorant:read_counts | Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `q` | query | string | no | Plain text across company name and description. | | `industries` | query | string | no | Pipe-separated industries. | | `industry` | query | string | no | One industry in plain words. | | `keywords` | query | string | no | Comma-separated words to look for, matched in the company's tags, industry, description and name. | | `technologies` | query | string | no | Pipe-separated technologies. | | `employee_range` | query | string | no | Comma-separated company sizes. One of 1-10, 11-50, 51-200, 201-500, 501-1000, 1001-5000, 5001-10000, 10000+, unknown. | | `company_name` | query | string | no | Company name, matched as written. Several companies: join the names with \|. | | `company_domain` | query | string | no | Website domain. | | `country` | query | string | no | Comma-separated countries. | | `state` | query | string | no | State or region. | | `city` | query | string | no | City. | | `exclude_industries` | query | string | no | Leave out these industries (pipe-separated). | | `exclude_industry` | query | string | no | Leave out industries in plain words. Comma means or. | | `exclude_keywords` | query | string | no | Leave out companies these keywords would find. Comma means or. | | `keyword_scope` | query | string | no | company (default): only what the company does, that is its name, tags, industry and description. people: only people's own skills and profile. any: both. One of company, people, any. | | `exclude_company_domain` | query | string | no | Leave out these website domains. Comma means or. | | `exclude_country` | query | string | no | Leave out these countries or regions. Comma means or. | | `exclude_state` | query | string | no | Leave out these states or provinces. Comma means or. | | `exclude_city` | query | string | no | Leave out these cities. Comma means or. | Example request ```bash curl -X GET "https://app.argorant.com/api/v1/companies/count?q=payroll%20software&industries=Software%20Development&keywords=payroll&employee_range=51-200&country=Germany&exclude_industries=Staffing%20and%20Recruiting&exclude_keywords=venture%20capital%2Cprivate%20equity&exclude_country=Switzerland" \ -H "Authorization: Bearer $ARGORANT_API_KEY" ``` Example answer (200) ```json { "count": 4120 } ``` It can answer with these errors (status and code): 401 unauthorized; 403 scope_missing; 429 rate_limited. ### Search companies `GET /api/v1/companies/search` Companies that match your filters, with name, domain, industry, size and place. Free. Pages stop at 10,000 results; narrow the filters for more. | Cost | What it does | Key scopes | | --- | --- | --- | | Free | Reads only | argorant:search_segments | Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `q` | query | string | no | Plain text across company name and description. | | `industries` | query | string | no | Pipe-separated industries. | | `industry` | query | string | no | One industry in plain words. | | `keywords` | query | string | no | Comma-separated words to look for, matched in the company's tags, industry, description and name. | | `technologies` | query | string | no | Pipe-separated technologies. | | `employee_range` | query | string | no | Comma-separated company sizes. One of 1-10, 11-50, 51-200, 201-500, 501-1000, 1001-5000, 5001-10000, 10000+, unknown. | | `company_name` | query | string | no | Company name, matched as written. Several companies: join the names with \|. | | `company_domain` | query | string | no | Website domain. | | `country` | query | string | no | Comma-separated countries. | | `state` | query | string | no | State or region. | | `city` | query | string | no | City. | | `exclude_industries` | query | string | no | Leave out these industries (pipe-separated). | | `exclude_industry` | query | string | no | Leave out industries in plain words. Comma means or. | | `exclude_keywords` | query | string | no | Leave out companies these keywords would find. Comma means or. | | `keyword_scope` | query | string | no | company (default): only what the company does, that is its name, tags, industry and description. people: only people's own skills and profile. any: both. One of company, people, any. | | `exclude_company_domain` | query | string | no | Leave out these website domains. Comma means or. | | `exclude_country` | query | string | no | Leave out these countries or regions. Comma means or. | | `exclude_state` | query | string | no | Leave out these states or provinces. Comma means or. | | `exclude_city` | query | string | no | Leave out these cities. Comma means or. | | `limit` | query | integer | no | Rows per page, 1 to 100 (default 10). | | `cursor` | query | string | no | The next_cursor of the previous page. Leave out for the first page. | | `offset` | query | integer | no | Rows to skip, as an alternative to cursor. | Example request ```bash curl -X GET "https://app.argorant.com/api/v1/companies/search?q=payroll%20software&industries=Software%20Development&keywords=payroll&employee_range=51-200&country=Germany&exclude_industries=Staffing%20and%20Recruiting&exclude_keywords=venture%20capital%2Cprivate%20equity&exclude_country=Switzerland&limit=10" \ -H "Authorization: Bearer $ARGORANT_API_KEY" ``` Example answer (200) ```json { "companies": [ { "record_id": "c_5b1e2f7a9c0d4e8f", "company_name": "Evenito AG", "display_name": "Evenito", "company_normalized": "Evenito", "company_domain": "evenito.com", "industry": "Software Development", "industry_display": "Software Development", "industries": [ "Software" ], "employee_range": "51-200", "employee_count": 120, "company_size": "51-200", "company_revenue": null, "year_founded": 2016, "linkedin_url": "https://www.linkedin.com/company/evenito", "description": "Event management software.", "location": "Zurich, Switzerland", "city": "Zurich", "state": null, "country": "Switzerland" } ], "total": 4120, "limit": 10, "offset": 0, "next_cursor": "bzoxMA", "has_more": true } ``` It can answer with these errors (status and code): 401 unauthorized; 403 scope_missing; 422 validation_error; 429 rate_limited. ### People at one company `GET /api/v1/companies/{domain}/people` How many people Argorant has at one company, how many of them have a work email on record, the company's profile, and a short preview of the people. Free. To go through all of them, use GET /api/v1/people/search with company_domain. | Cost | What it does | Key scopes | | --- | --- | --- | | Free | Reads only | argorant:read_counts, argorant:search_segments | Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `domain` | path | string | yes | The company's website domain. | | `title` | query | string | no | Only these titles. | | `seniority` | query | string | no | Only these seniority levels. One of Owner, Founder, Partner, C-Level, VP, Director, Manager, Senior, Entry, Intern. | | `departments` | query | string | no | Only these departments. | | `country` | query | string | no | Only people in these countries. | | `limit` | query | integer | no | Preview rows, 1 to 25 (default 5). | Example request ```bash curl -X GET "https://app.argorant.com/api/v1/companies/stripe.com/people?title=finance&limit=5" \ -H "Authorization: Bearer $ARGORANT_API_KEY" ``` Example answer (200) ```json { "company_domain": "stripe.com", "company": { "company": "Stripe", "company_domain": "stripe.com", "industry": "Financial Services", "employee_range": "5001-10000", "country": "United States" }, "people_count": 6120, "with_work_email": 4210, "people": [ { "record_id": "p_2a7c9e1b3d5f708192a3b4c5", "preview": "A* S", "title": "VP of Sales", "seniority": "VP", "departments": [ "Sales" ], "company": "Stripe", "company_normalized": "Stripe", "company_domain": "stripe.com", "city": "Zurich", "state": null, "country": "Switzerland", "industry": "Software Development", "industries": [ "Software", "Software Development" ] } ], "total": 6120, "limit": 5, "offset": 0, "next_cursor": null, "has_more": false, "more": "/api/v1/people/search?company_domain=stripe.com" } ``` It can answer with these errors (status and code): 401 unauthorized; 403 scope_missing; 404 not_found; 422 validation_error; 429 rate_limited. ### Enrich an email, a name or a domain `POST /api/v1/enrich` Three ways in. Send `email` to get the person behind it. Send `name` and `domain` to find that person at the company and get their checked work email. Send `domain` alone to get the company profile. The person ways cost 1 credit for a match whose email passes the check; the same person again is free, and a miss costs nothing. The company way is free. The company way needs only the argorant:read_counts scope. | Cost | What it does | Key scopes | | --- | --- | --- | | 1 credit per person found whose email passes the check; the same person again, misses and companies are free | spends credits | argorant:unlock_contacts | Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `Idempotency-Key` | header | string | no | Any unique text up to 128 characters. A retry with the same key and the same body within 24 hours returns the first answer (with the header Idempotent-Replayed: true) instead of doing the work twice. The same key with another body answers 409 idempotency_conflict. | Body fields (JSON) | Field | Type | Required | Description | | --- | --- | --- | --- | | `email` | string | no | A work email to look up. | | `name` | string | no | A person's full name, together with domain. | | `domain` | string | no | A company website domain. Alone it returns the company. | Example request ```bash curl -X POST "https://app.argorant.com/api/v1/enrich" \ -H "Authorization: Bearer $ARGORANT_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{"email":"alex@evenito.com"}' ``` Example answer (200) ```json { "found": true, "type": "person", "person_id": "p_8d4ba3d46cc885007c38e437", "person": { "record_id": "p_8d4ba3d46cc885007c38e437", "first_name": "Alex", "last_name": "Schneider", "full_name": "Alex Schneider", "title": "VP of Sales", "seniority": "VP", "departments": [ "Sales" ], "company": "Evenito AG", "company_normalized": "Evenito", "company_domain": "evenito.com", "email": "alex@evenito.com", "email_status": "valid", "linkedin_url": "https://www.linkedin.com/in/alexschneider", "city": "Zurich", "state": null, "country": "Switzerland", "industry": "Software Development", "industries": [ "Software", "Software Development" ] }, "charged": 1, "already_revealed": false, "deliverable": true, "verification": "valid" } ``` It can answer with these errors (status and code): 400 invalid_request; 401 unauthorized; 402 insufficient_credits; 403 scope_missing; 409 idempotency_conflict; 422 validation_error; 429 rate_limited. ### Email finder prices and balance `GET /api/v1/email-finder/pricing` The price per outcome, your credit balance and your limits. Free. Read it before a large list so you can show the most it can cost. | Cost | What it does | Key scopes | | --- | --- | --- | | Free | Reads only | argorant:unlock_contacts | Example request ```bash curl -X GET "https://app.argorant.com/api/v1/email-finder/pricing" \ -H "Authorization: Bearer $ARGORANT_API_KEY" ``` Example answer (200) ```json { "ok": true, "unit": "credit", "prices": { "found": 1, "catch_all": 1, "not_found": 0.25 }, "free_outcomes": [ "invalid_input", "no_mail_domain", "retry_later" ], "balance": { "credits": 412, "prepaid_no_result_lookups": 3, "unlimited": false }, "limits": { "per_minute": 30, "per_day": 2000, "used_today": 12, "bulk_max_rows": 10000, "throttled": false }, "summary": "1 credit per email found, 0.25 credits when nothing is found. Catch-all addresses cost 1 credit and are marked unconfirmed. Free when the input is invalid, the domain does not exist, or the mail server cannot be reached right now." } ``` It can answer with these errors (status and code): 401 unauthorized; 403 scope_missing; 429 rate_limited. ### Find a work email `POST /api/v1/email-finder/find` A person's name and company domain in, their work email out. 1 credit when the address is found and confirmed (`valid`). 1 credit when the domain accepts every address (`catch_all`); the most likely address comes back with `confirmed: false`. 0.25 credits when nothing is found. Free when the input is invalid, the domain has no email (`no_mail_domain`) or its mail server cannot be reached right now (`retry_later`). For more than a handful of people, start a list job. The first lookup that finds nothing takes 1 credit and keeps 0.75 for the next three such lookups, so each costs 0.25. | Cost | What it does | Key scopes | | --- | --- | --- | | 1 credit when found, 0.25 credits when nothing is found; bad input, domains without email and unreachable mail servers are free | spends credits | argorant:unlock_contacts | Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `Idempotency-Key` | header | string | no | Any unique text up to 128 characters. A retry with the same key and the same body within 24 hours returns the first answer (with the header Idempotent-Replayed: true) instead of doing the work twice. The same key with another body answers 409 idempotency_conflict. | Body fields (JSON) | Field | Type | Required | Description | | --- | --- | --- | --- | | `first_name` | string | no | First name. | | `last_name` | string | no | Last name. | | `name` | string | no | Full name instead of first_name and last_name; titles are ignored. | | `domain` | string | yes | The company domain. A website URL or an email at the company also works. Personal mail domains are refused. | Example request ```bash curl -X POST "https://app.argorant.com/api/v1/email-finder/find" \ -H "Authorization: Bearer $ARGORANT_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{"first_name":"Jane","last_name":"Doe","domain":"acme.com"}' ``` Example answer (200) ```json { "ok": true, "lookup_id": "fl_3f9c2a7b1d4e5f60718293a4", "status": "valid", "status_label": "Confirmed", "found": true, "email": "jane.doe@acme.com", "confirmed": true, "confidence": 95, "first_name": "Jane", "last_name": "Doe", "domain": "acme.com", "credits_charged": 1, "balance": { "credits": 411, "prepaid_no_result_lookups": 0, "unlimited": false }, "message": "Found and confirmed jane.doe@acme.com. 1 credit charged." } ``` It can answer with these errors (status and code): 400 invalid_request; 401 unauthorized; 402 insufficient_credits; 403 scope_missing; 409 idempotency_conflict; 422 validation_error; 429 rate_limited. ### List your list jobs `GET /api/v1/email-finder/jobs` Your list jobs, newest first. Free. | Cost | What it does | Key scopes | | --- | --- | --- | | Free | Reads only | argorant:unlock_contacts | Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `limit` | query | integer | no | Rows per page, 1 to 100 (default 20). | | `cursor` | query | string | no | The next_cursor of the previous page. Leave out for the first page. | | `offset` | query | integer | no | Rows to skip, as an alternative to cursor. | Example request ```bash curl -X GET "https://app.argorant.com/api/v1/email-finder/jobs?limit=20" \ -H "Authorization: Bearer $ARGORANT_API_KEY" ``` Example answer (200) ```json { "jobs": [ { "job_id": "fj_5d6e7f8a9b0c1d2e3f4a5b6c", "name": "Q4 accounts", "status": "done", "total": 120, "processed": 120, "credits_charged": 84.5 } ], "total": 1, "limit": 25, "offset": 0, "next_cursor": null, "has_more": false } ``` It can answer with these errors (status and code): 401 unauthorized; 403 scope_missing; 422 validation_error; 429 rate_limited. ### Find emails for a list `POST /api/v1/email-finder/jobs` A background job for up to 10,000 people. Send `rows` (first_name and last_name, or name, plus domain and an optional ref of your own) or `csv` text with a header row. Same prices per row as a single lookup; `maximum_charge` is the most the list can cost. Set `max_credits` to cap the spend: the job pauses at that limit. It also pauses when credits run out, at the daily limit (it goes on after midnight UTC) or when most lookups find nothing. Repeated rows and rows without a usable name or domain are skipped for free. | Cost | What it does | Key scopes | | --- | --- | --- | | Same as a single lookup, per row; capped by max_credits | spends credits | argorant:unlock_contacts | Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `Idempotency-Key` | header | string | no | Any unique text up to 128 characters. A retry with the same key and the same body within 24 hours returns the first answer (with the header Idempotent-Replayed: true) instead of doing the work twice. The same key with another body answers 409 idempotency_conflict. | Body fields (JSON) | Field | Type | Required | Description | | --- | --- | --- | --- | | `rows` | array of object | no | People to look up. Send rows or csv. | | `csv` | string | no | CSV text with a header row, instead of rows. Columns like first_name, last_name, name, domain, company_domain, website and id are recognised. | | `name` | string | no | A label for the list. | | `max_credits` | number | no | Spending limit for this list in credits. | Example request ```bash curl -X POST "https://app.argorant.com/api/v1/email-finder/jobs" \ -H "Authorization: Bearer $ARGORANT_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{"rows":[{"first_name":"Jane","last_name":"Doe","domain":"acme.com","ref":"crm-1042"},{"name":"Sam Lee","domain":"globex.io"}],"name":"Q4 accounts","max_credits":100}' ``` Example answer (200) ```json { "ok": true, "job": { "job_id": "fj_5d6e7f8a9b0c1d2e3f4a5b6c", "name": "Q4 accounts", "status": "queued", "paused_reason": null, "total": 2, "processed": 0, "credits_charged": 0, "max_credits": 100, "maximum_charge": 2, "results_url": "/api/v1/email-finder/jobs/fj_5d6e7f8a9b0c1d2e3f4a5b6c/results" } } ``` It can answer with these errors (status and code): 400 invalid_request; 401 unauthorized; 402 insufficient_credits; 403 scope_missing; 409 idempotency_conflict; 422 validation_error; 429 rate_limited. ### Get a list job `GET /api/v1/email-finder/jobs/{job_id}` Status, progress, counts per outcome, credits charged so far and, when paused, why in plain words. Free. | Cost | What it does | Key scopes | | --- | --- | --- | | Free | Reads only | argorant:unlock_contacts | Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `job_id` | path | string | yes | The list job id. | Example request ```bash curl -X GET "https://app.argorant.com/api/v1/email-finder/jobs/fj_5d6e7f8a9b0c1d2e3f4a5b6c" \ -H "Authorization: Bearer $ARGORANT_API_KEY" ``` Example answer (200) ```json { "ok": true, "job": { "job_id": "fj_5d6e7f8a9b0c1d2e3f4a5b6c", "name": "Q4 accounts", "status": "paused", "paused_reason": "spend_limit", "paused_message": "Paused: the spending limit for this list was reached. Resume with a higher limit.", "total": 120, "processed": 96, "credits_charged": 69.25, "max_credits": 70, "maximum_charge": 120 } } ``` It can answer with these errors (status and code): 401 unauthorized; 403 scope_missing; 404 not_found; 429 rate_limited. ### Get list results `GET /api/v1/email-finder/jobs/{job_id}/results` Result rows in input order, as JSON pages or one CSV (`format=csv`). Rows not done yet have status `pending`; rows held because credits ran out have status `unpaid` until the list is resumed. Free. | Cost | What it does | Key scopes | | --- | --- | --- | | Free | Reads only | argorant:unlock_contacts | Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `job_id` | path | string | yes | The list job id. | | `format` | query | string | no | json (default) or csv. One of json, csv. | | `limit` | query | integer | no | Rows per page, 1 to 5,000 (default 500). | | `cursor` | query | string | no | The next_cursor of the previous page. Leave out for the first page. | | `offset` | query | integer | no | Rows to skip, as an alternative to cursor. | Example request ```bash curl -X GET "https://app.argorant.com/api/v1/email-finder/jobs/fj_5d6e7f8a9b0c1d2e3f4a5b6c/results?limit=500" \ -H "Authorization: Bearer $ARGORANT_API_KEY" ``` Example answer (200) ```json { "job_id": "fj_5d6e7f8a9b0c1d2e3f4a5b6c", "status": "done", "results": [ { "row": 1, "ref": "crm-1042", "first_name": "Jane", "last_name": "Doe", "domain": "acme.com", "status": "valid", "email": "jane.doe@acme.com", "confirmed": true, "confidence": 95, "credits_charged": 1 } ], "total": 2, "limit": 500, "offset": 0, "next_cursor": null, "has_more": false } ``` It can answer with these errors (status and code): 401 unauthorized; 403 scope_missing; 404 not_found; 422 validation_error; 429 rate_limited. ### Resume a list job `POST /api/v1/email-finder/jobs/{job_id}/resume` Continue a paused list, with a new total spending limit if you like. Rows already done are never charged again. | Cost | What it does | Key scopes | | --- | --- | --- | | Same as a single lookup, per remaining row | spends credits | argorant:unlock_contacts | Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `job_id` | path | string | yes | The list job id. | | `Idempotency-Key` | header | string | no | Any unique text up to 128 characters. A retry with the same key and the same body within 24 hours returns the first answer (with the header Idempotent-Replayed: true) instead of doing the work twice. The same key with another body answers 409 idempotency_conflict. | Body fields (JSON) | Field | Type | Required | Description | | --- | --- | --- | --- | | `max_credits` | number | no | New total spending limit for the list. | Example request ```bash curl -X POST "https://app.argorant.com/api/v1/email-finder/jobs/fj_5d6e7f8a9b0c1d2e3f4a5b6c/resume" \ -H "Authorization: Bearer $ARGORANT_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{"max_credits":150}' ``` Example answer (200) ```json { "ok": true, "job": { "job_id": "fj_5d6e7f8a9b0c1d2e3f4a5b6c", "status": "queued", "max_credits": 150 } } ``` It can answer with these errors (status and code): 401 unauthorized; 403 scope_missing; 404 not_found; 409 conflict, idempotency_conflict; 422 validation_error; 429 rate_limited. ### Cancel a list job `POST /api/v1/email-finder/jobs/{job_id}/cancel` Stop a list. Rows not done yet are never looked up or charged; charges already made stay. | Cost | What it does | Key scopes | | --- | --- | --- | | Free | writes | argorant:unlock_contacts | Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `job_id` | path | string | yes | The list job id. | | `Idempotency-Key` | header | string | no | Any unique text up to 128 characters. A retry with the same key and the same body within 24 hours returns the first answer (with the header Idempotent-Replayed: true) instead of doing the work twice. The same key with another body answers 409 idempotency_conflict. | Example request ```bash curl -X POST "https://app.argorant.com/api/v1/email-finder/jobs/fj_5d6e7f8a9b0c1d2e3f4a5b6c/cancel" \ -H "Authorization: Bearer $ARGORANT_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{}' ``` Example answer (200) ```json { "ok": true, "job": { "job_id": "fj_5d6e7f8a9b0c1d2e3f4a5b6c", "status": "cancelled" } } ``` It can answer with these errors (status and code): 401 unauthorized; 403 scope_missing; 404 not_found; 409 idempotency_conflict; 429 rate_limited. ### Recent single lookups `GET /api/v1/email-finder/lookups` Your recent single lookups, newest first, with outcome and charge. Free. | Cost | What it does | Key scopes | | --- | --- | --- | | Free | Reads only | argorant:unlock_contacts | Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `limit` | query | integer | no | Rows per page, 1 to 200 (default 50). | | `cursor` | query | string | no | The next_cursor of the previous page. Leave out for the first page. | | `offset` | query | integer | no | Rows to skip, as an alternative to cursor. | Example request ```bash curl -X GET "https://app.argorant.com/api/v1/email-finder/lookups?limit=50" \ -H "Authorization: Bearer $ARGORANT_API_KEY" ``` Example answer (200) ```json { "lookups": [ { "lookup_id": "fl_3f9c2a7b1d4e5f60718293a4", "first_name": "Jane", "last_name": "Doe", "domain": "acme.com", "status": "valid", "email": "jane.doe@acme.com", "confirmed": true, "credits_charged": 1, "created_at": "2026-10-07T12:00:00Z" } ], "total": 1, "limit": 50, "offset": 0, "next_cursor": null, "has_more": false } ``` It can answer with these errors (status and code): 401 unauthorized; 403 scope_missing; 422 validation_error; 429 rate_limited. ### Quote a list check `POST /api/v1/verifications/quote` Send the emails of your own list (up to 5,000 rows, 1,000 different addresses) and get the most the check can cost. Addresses checked recently are free. Nothing is charged and nothing is checked yet. Show `maximum_charge` to the user and start only after their yes. | Cost | What it does | Key scopes | | --- | --- | --- | | Free | Reads only | argorant:verify_emails | Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `Idempotency-Key` | header | string | no | Any unique text up to 128 characters. A retry with the same key and the same body within 24 hours returns the first answer (with the header Idempotent-Replayed: true) instead of doing the work twice. The same key with another body answers 409 idempotency_conflict. | Body fields (JSON) | Field | Type | Required | Description | | --- | --- | --- | --- | | `emails` | array of string | yes | The addresses to check. | Example request ```bash curl -X POST "https://app.argorant.com/api/v1/verifications/quote" \ -H "Authorization: Bearer $ARGORANT_API_KEY" \ -H "Content-Type: application/json" \ -d '{"emails":["jane.doe@acme.com","sam@globex.io","info@initech.example"]}' ``` Example answer (200) ```json { "quote_id": "4b1d2c3e4f5a6b7c8d9e0f1a2b3c4d5e", "expires_at": "2026-10-07T12:15:00+00:00", "unique_addresses": 3, "to_check": 2, "checked_recently_free": 1, "duplicates_removed": 0, "invalid_rows": [], "maximum_charge": 1, "credits_per_check": 0.5, "approval_required": true, "next_step": "Show the maximum charge to the user and start only after their yes: POST /api/v1/verifications with quote_id and approved_maximum_charge. Addresses checked recently are free." } ``` It can answer with these errors (status and code): 400 invalid_request; 401 unauthorized; 403 scope_missing; 409 idempotency_conflict; 422 validation_error; 429 rate_limited. ### Start a list check `POST /api/v1/verifications` Checks the addresses of a quote. The list comes from the quote, so it cannot change after the user said yes. `approved_maximum_charge` is the most the user agreed to pay; the check never costs more. Half a credit per fresh check, rounded up per run. Starting the same quote again returns the same run. | Cost | What it does | Key scopes | | --- | --- | --- | | 0.5 credit per address that needs a fresh check, never more than approved_maximum_charge | spends credits | argorant:verify_emails | Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `Idempotency-Key` | header | string | no | Any unique text up to 128 characters. A retry with the same key and the same body within 24 hours returns the first answer (with the header Idempotent-Replayed: true) instead of doing the work twice. The same key with another body answers 409 idempotency_conflict. | Body fields (JSON) | Field | Type | Required | Description | | --- | --- | --- | --- | | `quote_id` | string | yes | The quote the user agreed to. | | `approved_maximum_charge` | integer | yes | The most the user agreed to pay, in credits (0 to 1,000). | Example request ```bash curl -X POST "https://app.argorant.com/api/v1/verifications" \ -H "Authorization: Bearer $ARGORANT_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{"quote_id":"4b1d2c3e4f5a6b7c8d9e0f1a2b3c4d5e","approved_maximum_charge":1}' ``` Example answer (201) ```json { "run_id": "9e8d7c6b5a4f3e2d1c0b9a8f7e6d5c4b", "total": 3, "done": 1, "complete": false, "summary": { "valid": 1, "pending": 2 }, "credits_charged": 1, "checks_charged": 2, "results_url": "https://app.argorant.com/verify?run=9e8d7c6b5a4f3e2d1c0b9a8f7e6d5c4b" } ``` It can answer with these errors (status and code): 401 unauthorized; 402 insufficient_credits; 403 scope_missing; 404 quote_not_found; 409 idempotency_conflict; 422 validation_error; 429 rate_limited. ### Get a list check `GET /api/v1/verifications/{run_id}` Progress and how many addresses got each result: valid, invalid, catch_all (the domain accepts every address), risky, unknown. The full list with each address stays in the app at results_url. Free. | Cost | What it does | Key scopes | | --- | --- | --- | | Free | Reads only | argorant:verify_emails | Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `run_id` | path | string | yes | The run id from start. | Example request ```bash curl -X GET "https://app.argorant.com/api/v1/verifications/9e8d7c6b5a4f3e2d1c0b9a8f7e6d5c4b" \ -H "Authorization: Bearer $ARGORANT_API_KEY" ``` Example answer (200) ```json { "run_id": "9e8d7c6b5a4f3e2d1c0b9a8f7e6d5c4b", "total": 3, "done": 3, "complete": true, "summary": { "valid": 2, "invalid": 1 }, "credits_charged": 1, "checks_charged": 2, "results_url": "https://app.argorant.com/verify?run=9e8d7c6b5a4f3e2d1c0b9a8f7e6d5c4b" } ``` It can answer with these errors (status and code): 401 unauthorized; 403 scope_missing; 404 not_found; 429 rate_limited. ### List saved lists `GET /api/v1/lists` Your saved lists and saved searches, most recently changed first. | Cost | What it does | Key scopes | | --- | --- | --- | | Free | Reads only | argorant:manage_lists | Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `kind` | query | string | no | all (default), records (people you picked) or filtered (saved searches). One of all, records, filtered. | | `limit` | query | integer | no | Rows per page, 1 to 100 (default 25). | | `cursor` | query | string | no | The next_cursor of the previous page. Leave out for the first page. | | `offset` | query | integer | no | Rows to skip, as an alternative to cursor. | Example request ```bash curl -X GET "https://app.argorant.com/api/v1/lists?limit=25" \ -H "Authorization: Bearer $ARGORANT_API_KEY" ``` Example answer (200) ```json { "lists": [ { "list_id": 312, "name": "DACH CFOs", "record_type": "person", "selection_mode": "filtered", "filters": { "title": "CFO", "country": "Germany,Austria,Switzerland", "record_type": "person" }, "snapshot_total": 8412, "item_count": 8412, "created_at": "2026-10-07T09:00:00+00:00", "updated_at": "2026-10-07T09:02:10+00:00" } ], "total": 1, "limit": 25, "offset": 0, "next_cursor": null, "has_more": false } ``` It can answer with these errors (status and code): 401 unauthorized; 403 scope_missing; 422 validation_error; 429 rate_limited. ### Create a list `POST /api/v1/lists` Save a search with `filters`, or the people you picked with `record_ids`. The answer comes back at once: a saved search fills itself in the background (`materialize` has the job), and GET /api/v1/lists/{list_id}/fill says when it is done. Every filter applies, the same as in search. Saving costs nothing and reveals no contacts. snapshot_total is the number of people when the count finishes in time. Otherwise it is null, with count_status pending and a status_url to follow, never 0. The list keeps the request as you sent it under filters.request, and business_email_only and exclude_assistants as they applied. | Cost | What it does | Key scopes | | --- | --- | --- | | Free | writes | argorant:manage_lists | Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `Idempotency-Key` | header | string | no | Any unique text up to 128 characters. A retry with the same key and the same body within 24 hours returns the first answer (with the header Idempotent-Replayed: true) instead of doing the work twice. The same key with another body answers 409 idempotency_conflict. | Body fields (JSON) | Field | Type | Required | Description | | --- | --- | --- | --- | | `name` | string | yes | List name, up to 200 characters. | | `filters` | object | no | A search to save, same names as people search. | | `record_ids` | array of string | no | Or exactly these people, by record id. | Example request ```bash curl -X POST "https://app.argorant.com/api/v1/lists" \ -H "Authorization: Bearer $ARGORANT_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{"name":"DACH CFOs","filters":{"title":"CFO","country":"Germany,Austria,Switzerland"}}' ``` Example answer (201) ```json { "list_id": 312, "name": "DACH CFOs", "record_type": "person", "selection_mode": "filtered", "filters": { "title": "CFO", "country": "Germany,Austria,Switzerland", "record_type": "person" }, "snapshot_total": 8412, "item_count": 8412, "created_at": "2026-10-07T09:00:00+00:00", "updated_at": "2026-10-07T09:02:10+00:00", "materialize": { "status": "processing", "target_rows": 8412, "scanned_rows": 0, "inserted_rows": 0 } } ``` It can answer with these errors (status and code): 400 invalid_request; 401 unauthorized; 403 scope_missing; 409 idempotency_conflict; 422 validation_error; 429 rate_limited. ### List fill status `GET /api/v1/lists/{list_id}/fill` Whether a list is still filling after a save or an add, with the people so far and a plain summary. Adds to a list that is still filling wait for their turn and run after it, one after the other. Free. The answer is short so it can be checked often. It has the status, the counts, progress_percent and eta_seconds. A size that is still being counted is null, never 0. Add verbose=true to see the saved search as well. fill.status is queued (waiting for its turn, with queue_position), processing, done or failed. | Cost | What it does | Key scopes | | --- | --- | --- | | Free | Reads only | argorant:manage_lists | Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `list_id` | path | integer | yes | The list id from create or list. | | `verbose` | query | boolean | no | true adds the saved search (filters) to the answer. Leave it out when you check again and again. | | `fields` | query | string | no | filters adds the saved search to the answer, like verbose=true. | Example request ```bash curl -X GET "https://app.argorant.com/api/v1/lists/312/fill?fields=filters" \ -H "Authorization: Bearer $ARGORANT_API_KEY" ``` Example answer (200) ```json { "ok": true, "list": { "list_id": 312, "name": "DACH CFOs", "record_type": "person", "selection_mode": "filtered", "filters": { "title": "CFO", "country": "Germany,Austria,Switzerland", "record_type": "person" }, "snapshot_total": 8412, "item_count": 8412, "created_at": "2026-10-07T09:00:00+00:00", "updated_at": "2026-10-07T09:02:10+00:00" }, "fill": { "job_id": 913, "status": "processing", "target_rows": 8412, "inserted_rows": 5120, "scanned_rows": 5120, "error": null }, "filling": true, "summary": "The list is still filling: 5,120 people so far. Check again in a minute." } ``` It can answer with these errors (status and code): 401 unauthorized; 403 scope_missing; 404 not_found; 422 validation_error; 429 rate_limited. ### Get a list `GET /api/v1/lists/{list_id}` One list with its name, filters, size and up to 200 record ids as a sample. | Cost | What it does | Key scopes | | --- | --- | --- | | Free | Reads only | argorant:manage_lists | Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `list_id` | path | integer | yes | The list id from create or list. | Example request ```bash curl -X GET "https://app.argorant.com/api/v1/lists/312" \ -H "Authorization: Bearer $ARGORANT_API_KEY" ``` Example answer (200) ```json { "list_id": 312, "name": "DACH CFOs", "record_type": "person", "selection_mode": "filtered", "filters": { "title": "CFO", "country": "Germany,Austria,Switzerland", "record_type": "person" }, "snapshot_total": 8412, "item_count": 8412, "created_at": "2026-10-07T09:00:00+00:00", "updated_at": "2026-10-07T09:02:10+00:00", "sample_record_ids": [ "p_8d4ba3d46cc885007c38e437" ] } ``` It can answer with these errors (status and code): 401 unauthorized; 403 scope_missing; 404 not_found; 429 rate_limited. ### Rename a list `PATCH /api/v1/lists/{list_id}` Give a list a new name. | Cost | What it does | Key scopes | | --- | --- | --- | | Free | writes | argorant:manage_lists | Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `list_id` | path | integer | yes | The list id from create or list. | | `Idempotency-Key` | header | string | no | Any unique text up to 128 characters. A retry with the same key and the same body within 24 hours returns the first answer (with the header Idempotent-Replayed: true) instead of doing the work twice. The same key with another body answers 409 idempotency_conflict. | Body fields (JSON) | Field | Type | Required | Description | | --- | --- | --- | --- | | `name` | string | yes | The new name. | Example request ```bash curl -X PATCH "https://app.argorant.com/api/v1/lists/312" \ -H "Authorization: Bearer $ARGORANT_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{"name":"DACH CFOs, Q4"}' ``` Example answer (200) ```json { "list_id": 312, "name": "DACH CFOs, Q4", "record_type": "person", "selection_mode": "filtered", "filters": { "title": "CFO", "country": "Germany,Austria,Switzerland", "record_type": "person" }, "snapshot_total": 8412, "item_count": 8412, "created_at": "2026-10-07T09:00:00+00:00", "updated_at": "2026-10-07T09:02:10+00:00" } ``` It can answer with these errors (status and code): 401 unauthorized; 403 scope_missing; 404 not_found; 409 idempotency_conflict; 422 validation_error; 429 rate_limited. ### Delete a list `DELETE /api/v1/lists/{list_id}` Deletes the list. Exports made from it and campaigns that enrolled it keep their people. | Cost | What it does | Key scopes | | --- | --- | --- | | Free | writes | argorant:manage_lists | Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `list_id` | path | integer | yes | The list id from create or list. | | `Idempotency-Key` | header | string | no | Any unique text up to 128 characters. A retry with the same key and the same body within 24 hours returns the first answer (with the header Idempotent-Replayed: true) instead of doing the work twice. The same key with another body answers 409 idempotency_conflict. | Example request ```bash curl -X DELETE "https://app.argorant.com/api/v1/lists/312" \ -H "Authorization: Bearer $ARGORANT_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" ``` Example answer (200) ```json { "deleted": true, "list_id": 312 } ``` It can answer with these errors (status and code): 401 unauthorized; 403 scope_missing; 404 not_found; 409 idempotency_conflict; 429 rate_limited. ### People in a list `GET /api/v1/lists/{list_id}/people` The people in a list, a page at a time. Contact details stay hidden, as in a search, unless this account already unlocked them: then the row shows the name, the email and the profile URL, and email_unlocked is true. Free. With offset, use a multiple of limit. | Cost | What it does | Key scopes | | --- | --- | --- | | Free | Reads only | argorant:manage_lists | Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `list_id` | path | integer | yes | The list id from create or list. | | `limit` | query | integer | no | Rows per page, 1 to 100 (default 25). | | `cursor` | query | string | no | The next_cursor of the previous page. Leave out for the first page. | | `offset` | query | integer | no | Rows to skip, as an alternative to cursor. | Example request ```bash curl -X GET "https://app.argorant.com/api/v1/lists/312/people?limit=25" \ -H "Authorization: Bearer $ARGORANT_API_KEY" ``` Example answer (200) ```json { "list": { "list_id": 312, "name": "DACH CFOs" }, "people": [ { "record_id": "p_8d4ba3d46cc885007c38e437", "preview": "A* S", "title": "VP of Sales", "seniority": "VP", "departments": [ "Sales" ], "company": "Evenito AG", "company_normalized": "Evenito", "company_domain": "evenito.com", "city": "Zurich", "state": null, "country": "Switzerland", "industry": "Software Development", "industries": [ "Software Development" ], "email_unlocked": false, "phone_unlocked": false }, { "record_id": "p_2a7c9e1b3d5f708192a3b4c5", "first_name": "Jane", "last_name": "Doe", "full_name": "Jane Doe", "title": "CFO", "seniority": "C-Level", "departments": [ "Finance" ], "company": "Acme GmbH", "company_normalized": "Acme", "company_domain": "acme.de", "city": "Munich", "state": "Bavaria", "country": "Germany", "industry": "Manufacturing", "industries": [ "Manufacturing" ], "email_unlocked": true, "email": "jane.doe@acme.de", "linkedin_url": "https://www.linkedin.com/in/janedoe", "phone_unlocked": false } ], "total": 8412, "limit": 25, "offset": 0, "next_cursor": "bzoyNQ", "has_more": true } ``` It can answer with these errors (status and code): 401 unauthorized; 403 scope_missing; 404 not_found; 422 validation_error; 429 rate_limited. ### Add people to a list `POST /api/v1/lists/{list_id}/items` Adds people to an existing list; people already in it are skipped. Send `record_ids`, or `filters` to add every match of a search, so "add the rest" is the same search again and only new people join. A large add, or an add to a list that is still filling, runs in the background after the fill before it (see GET /api/v1/lists/{list_id}/fill). | Cost | What it does | Key scopes | | --- | --- | --- | | Free | writes | argorant:manage_lists | Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `list_id` | path | integer | yes | The list id from create or list. | | `Idempotency-Key` | header | string | no | Any unique text up to 128 characters. A retry with the same key and the same body within 24 hours returns the first answer (with the header Idempotent-Replayed: true) instead of doing the work twice. The same key with another body answers 409 idempotency_conflict. | Body fields (JSON) | Field | Type | Required | Description | | --- | --- | --- | --- | | `record_ids` | array of string | no | People to add. | | `filters` | object | no | Or add every match of this search. | Example request ```bash curl -X POST "https://app.argorant.com/api/v1/lists/312/items" \ -H "Authorization: Bearer $ARGORANT_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{"filters":{"title":"CFO","country":"Switzerland"}}' ``` Example answer (200) ```json { "list_id": 312, "name": "DACH CFOs", "added": 1204, "duplicates": 18, "item_count": 9616, "summary": "1,222 people for \"DACH CFOs\" (list 312): 1,204 added, 18 already in it. The list now holds 9,616." } ``` It can answer with these errors (status and code): 400 invalid_request; 401 unauthorized; 403 scope_missing; 404 not_found; 409 idempotency_conflict; 422 validation_error; 429 rate_limited. ### Export a list `POST /api/v1/lists/{list_id}/export` Builds a CSV of the list's people. Every email is checked when the file is built and you pay only for people whose email passes. People you exported before are left out unless you set `exclude_previously_exported: false`. With `include_phones: true` each phone number written into the file costs 10 more credits (from the Pro plan). | Cost | What it does | Key scopes | | --- | --- | --- | | 1 credit per contact whose email passes the check, plus 10 per phone number with include_phones | spends credits | argorant:create_exports, argorant:manage_lists | Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `list_id` | path | integer | yes | The list id from create or list. | | `Idempotency-Key` | header | string | no | Any unique text up to 128 characters. A retry with the same key and the same body within 24 hours returns the first answer (with the header Idempotent-Replayed: true) instead of doing the work twice. The same key with another body answers 409 idempotency_conflict. | Body fields (JSON) | Field | Type | Required | Description | | --- | --- | --- | --- | | `limit` | integer | no | Most rows in the file. | | `exclude_previously_exported` | boolean | no | Leave out people you exported before (default true). | | `include_phones` | boolean | no | Add phone numbers, 10 credits each (default false). | | `email_when_done` | boolean | no | Email you when the file is ready. | Example request ```bash curl -X POST "https://app.argorant.com/api/v1/lists/312/export" \ -H "Authorization: Bearer $ARGORANT_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{"limit":5000,"exclude_previously_exported":true,"include_phones":false}' ``` Example answer (201) ```json { "type": "job", "job_id": 84260, "status": "queued", "source_list_id": 312, "include_phones": false, "phone_price": 0, "status_url": "/api/v1/exports/84260", "download_url": "/api/v1/exports/84260/download" } ``` It can answer with these errors (status and code): 401 unauthorized; 402 insufficient_credits; 403 scope_missing; 404 not_found; 409 idempotency_conflict; 422 validation_error; 429 daily_limit_reached, rate_limited. ### List exports `GET /api/v1/exports` Your exports, newest first, with status, rows and whether the file can be downloaded. | Cost | What it does | Key scopes | | --- | --- | --- | | Free | Reads only | argorant:create_exports | Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `limit` | query | integer | no | Rows per page, 1 to 100 (default 25). | | `cursor` | query | string | no | The next_cursor of the previous page. Leave out for the first page. | | `offset` | query | integer | no | Rows to skip, as an alternative to cursor. | Example request ```bash curl -X GET "https://app.argorant.com/api/v1/exports?limit=25" \ -H "Authorization: Bearer $ARGORANT_API_KEY" ``` Example answer (200) ```json { "exports": [ { "job_id": 84213, "name": "CFOs Germany", "status": "done", "progress_pct": 100, "limit": 500, "total_rows": 500, "verified_rows": 482, "no_email_rows": 0, "grade_counts": { "valid": 470, "catch_all": 12 }, "downloadable": true, "include_phones": false, "exclude_previously_exported": true, "credits_charged": 482, "emails_billed": 482, "phones_billed": 0, "error_message": null, "billing_note": "482 contacts with a working email were charged 1 credit each.", "batch_id": null, "chunk_index": null, "filters": { "title": "CFO", "country": "Germany" }, "created_at": "2026-10-07T09:14:02+00:00", "started_at": "2026-10-07T09:14:03+00:00", "completed_at": "2026-10-07T09:16:40+00:00", "status_url": "/api/v1/exports/84213", "download_url": "/api/v1/exports/84213/download" } ], "total": 1, "limit": 25, "offset": 0, "next_cursor": null, "has_more": false } ``` It can answer with these errors (status and code): 401 unauthorized; 403 scope_missing; 422 validation_error; 429 rate_limited. ### Create an export `POST /api/v1/exports` Builds a CSV of the people who match your filters. Every email is checked when the file is built and you pay only for the ones that pass. Up to 50,000 rows make one file; more become a batch of files. People you exported before are left out by default. Poll the export, then download the CSV. Every people filter applies, include and exclude alike. A search that leaves people out, limits where keywords look or uses a title match mode, or uses the newer filters (size and revenue ranges, radius, gender or income) is exported up to 50,000 people at a time; for more, save it as a list (it has no limit) and export the list. | Cost | What it does | Key scopes | | --- | --- | --- | | 1 credit per contact whose email passes the check, plus 10 per phone number with include_phones | spends credits | argorant:create_exports | Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `Idempotency-Key` | header | string | no | Any unique text up to 128 characters. A retry with the same key and the same body within 24 hours returns the first answer (with the header Idempotent-Replayed: true) instead of doing the work twice. The same key with another body answers 409 idempotency_conflict. | Body fields (JSON) | Field | Type | Required | Description | | --- | --- | --- | --- | | `filters` | object | yes | The people filters, same names as search. | | `limit` | integer | no | Most rows (default 1,000). Above 50,000 the export becomes a batch of files, up to 500,000 rows. | | `exclude_previously_exported` | boolean | no | Leave out people you exported before (default true). | | `include_phones` | boolean | no | Add phone numbers, 10 credits each (default false, from the Pro plan). | | `grades` | array of string | no | The results to include, valid and catch_all (default both). | | `email_when_done` | boolean | no | Email you when the file is ready. | Example request ```bash curl -X POST "https://app.argorant.com/api/v1/exports" \ -H "Authorization: Bearer $ARGORANT_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{"filters":{"title":"CFO","country":"Germany","employee_range":"51-200"},"limit":500,"exclude_previously_exported":true}' ``` Example answer (201) ```json { "type": "job", "job_id": 84213, "status": "queued", "status_url": "/api/v1/exports/84213", "download_url": "/api/v1/exports/84213/download" } ``` It can answer with these errors (status and code): 400 invalid_request; 401 unauthorized; 402 insufficient_credits; 403 scope_missing, permission_missing; 409 idempotency_conflict; 422 validation_error; 429 daily_limit_reached, rate_limited. ### Get an export `GET /api/v1/exports/{job_id}` Where an export is. When `status` is `done`, download the CSV. | Cost | What it does | Key scopes | | --- | --- | --- | | Free | Reads only | argorant:create_exports | Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `job_id` | path | integer | yes | The export id from create or list. | Example request ```bash curl -X GET "https://app.argorant.com/api/v1/exports/84213" \ -H "Authorization: Bearer $ARGORANT_API_KEY" ``` Example answer (200) ```json { "job_id": 84213, "name": "CFOs Germany", "status": "done", "progress_pct": 100, "limit": 500, "total_rows": 500, "verified_rows": 482, "no_email_rows": 0, "grade_counts": { "valid": 470, "catch_all": 12 }, "downloadable": true, "include_phones": false, "exclude_previously_exported": true, "credits_charged": 482, "emails_billed": 482, "phones_billed": 0, "error_message": null, "billing_note": "482 contacts with a working email were charged 1 credit each.", "batch_id": null, "chunk_index": null, "filters": { "title": "CFO", "country": "Germany" }, "created_at": "2026-10-07T09:14:02+00:00", "started_at": "2026-10-07T09:14:03+00:00", "completed_at": "2026-10-07T09:16:40+00:00", "status_url": "/api/v1/exports/84213", "download_url": "/api/v1/exports/84213/download" } ``` It can answer with these errors (status and code): 401 unauthorized; 403 scope_missing; 404 not_found; 429 rate_limited. ### Download an export `GET /api/v1/exports/{job_id}/download` The finished file as CSV. Free to download again. | Cost | What it does | Key scopes | | --- | --- | --- | | Free | Reads only | argorant:create_exports | Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `job_id` | path | integer | yes | The export id from create or list. | | `grades` | query | string | no | The rows to include, valid (default), valid,catch_all or all. One of valid, valid,catch_all, all. | Example request ```bash curl -X GET "https://app.argorant.com/api/v1/exports/84213/download?grades=valid" \ -H "Authorization: Bearer $ARGORANT_API_KEY" ``` Example answer (200) ```csv First Name,Last Name,Title,Company,Company Normalized,Email,Verify Status,Phone,LinkedIn,City,State,Country Alex,Schneider,VP of Sales,Evenito AG,Evenito,alex@evenito.com,valid,,https://www.linkedin.com/in/alexschneider,Zurich,,Switzerland ``` It can answer with these errors (status and code): 401 unauthorized; 403 scope_missing; 404 not_found; 410 gone; 429 rate_limited. ### Get an export batch `GET /api/v1/export-batches/{batch_id}` An export above 50,000 rows runs as a batch of files. This shows each file with its status and download path. | Cost | What it does | Key scopes | | --- | --- | --- | | Free | Reads only | argorant:create_exports | Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `batch_id` | path | integer | yes | The batch id from create. | Example request ```bash curl -X GET "https://app.argorant.com/api/v1/export-batches/912" \ -H "Authorization: Bearer $ARGORANT_API_KEY" ``` Example answer (200) ```json { "batch_id": 912, "status": "processing", "requested_rows": 120000, "chunk_size": 50000, "total_chunks": 3, "chunks": [ { "job_id": 84301, "name": "CFOs Germany", "status": "done", "progress_pct": 100, "limit": 500, "total_rows": 500, "verified_rows": 482, "no_email_rows": 0, "grade_counts": { "valid": 470, "catch_all": 12 }, "downloadable": true, "include_phones": false, "exclude_previously_exported": true, "credits_charged": 482, "emails_billed": 482, "phones_billed": 0, "error_message": null, "billing_note": "482 contacts with a working email were charged 1 credit each.", "batch_id": null, "chunk_index": null, "filters": { "title": "CFO", "country": "Germany" }, "created_at": "2026-10-07T09:14:02+00:00", "started_at": "2026-10-07T09:14:03+00:00", "completed_at": "2026-10-07T09:16:40+00:00", "status_url": "/api/v1/exports/84213", "download_url": "/api/v1/exports/84213/download" } ] } ``` It can answer with these errors (status and code): 401 unauthorized; 403 scope_missing; 404 not_found; 429 rate_limited. ### List campaigns `GET /api/v1/campaigns` Every campaign in your workspace with status and counts: people, sent, replies, positive replies, bounces, emails and sending mailboxes. | Cost | What it does | Key scopes | | --- | --- | --- | | Free | Reads only | argorant:read_counts | Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `limit` | query | integer | no | Rows per page, 1 to 500 (default 100). | | `cursor` | query | string | no | The next_cursor of the previous page. Leave out for the first page. | | `offset` | query | integer | no | Rows to skip, as an alternative to cursor. | Example request ```bash curl -X GET "https://app.argorant.com/api/v1/campaigns?limit=100" \ -H "Authorization: Bearer $ARGORANT_API_KEY" ``` Example answer (200) ```json { "campaigns": [ { "id": "7f3a2c1e-9b4d-4e8a-a1c2-5d6e7f8a9b0c", "name": "Q4 CFO outreach", "status": "active", "lead_count": 1188, "queued_count": 0, "sent_count": 412, "replied_count": 19, "positive_reply_count": 6, "bounced_count": 0, "step_count": 3, "inbox_count": 12, "daily_limit": 40, "default_timezone": "Europe/Berlin", "created_at": "2026-10-07T09:00:00+00:00", "updated_at": "2026-10-07T09:00:00+00:00", "url": "https://app.argorant.com/campaigns/7f3a2c1e-9b4d-4e8a-a1c2-5d6e7f8a9b0c" } ], "total": 1, "limit": 25, "offset": 0, "next_cursor": null, "has_more": false } ``` It can answer with these errors (status and code): 401 unauthorized; 403 scope_missing; 422 validation_error; 429 rate_limited. ### Create a campaign `POST /api/v1/campaigns` Creates a draft. Nothing sends until you launch. Takes every setting of the update call. Defaults: 100 emails a day, 08:00 to 17:00 America/New_York, weekdays only, a pause of 60 to 120 minutes between two emails from one mailbox, plain text, no unsubscribe line. | Cost | What it does | Key scopes | | --- | --- | --- | | Free | writes | argorant:manage_lists | Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `Idempotency-Key` | header | string | no | Any unique text up to 128 characters. A retry with the same key and the same body within 24 hours returns the first answer (with the header Idempotent-Replayed: true) instead of doing the work twice. The same key with another body answers 409 idempotency_conflict. | Body fields (JSON) | Field | Type | Required | Description | | --- | --- | --- | --- | | `name` | string | yes | Campaign name. | | `daily_limit` | integer | no | Emails a day for the whole campaign (default 100). | | `per_mailbox_daily_limit` | integer | no | Most emails a day from one mailbox. | | `max_active_mailboxes` | integer | no | Rotate between at most this many mailboxes. | | `timezone` | string | no | Time zone name, for example Europe/Berlin (default America/New_York). | | `timezone_mode` | string | no | fixed: the campaign's time zone. lead: each person's local time. One of fixed, lead. | | `window_start` | string | no | Sending starts, HH:MM (default 08:00). | | `window_end` | string | no | Sending stops, HH:MM (default 17:00). | | `skip_weekends` | boolean | no | No emails on Saturday and Sunday (default true). | | `gap_minutes_min` | integer | no | Shortest pause between two emails from one mailbox (default 60). | | `gap_minutes_max` | integer | no | Longest pause (default 120). | | `include_unsubscribe` | boolean | no | Add an opt-out line at the bottom of every email (default false). | | `stop_on_reply` | boolean | no | A reply ends that person's emails (default true). | | `planned_start_date` | string | no | YYYY-MM-DD. A launch before this date waits. | | `tags` | array of string | no | Your own tags. | | `auto_pause` | boolean | no | Pause by itself when bounces are high or the mailboxes are offline. | | `auto_pause_bounce_rate_pct` | number | no | Bounce share in percent that pauses, 1 to 50 (default 10). | | `accepted_email_grades` | array of string | no | Which email results may join: valid always; add catch_all, unknown or risky to accept them. | Example request ```bash curl -X POST "https://app.argorant.com/api/v1/campaigns" \ -H "Authorization: Bearer $ARGORANT_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{"name":"Q4 CFO outreach","daily_limit":40,"per_mailbox_daily_limit":20,"timezone":"Europe/Berlin","window_start":"08:00","window_end":"17:00","skip_weekends":true,"include_unsubscribe":false,"tags":["q4"]}' ``` Example answer (200) ```json { "campaign": { "id": "7f3a2c1e-9b4d-4e8a-a1c2-5d6e7f8a9b0c", "name": "Q4 CFO outreach", "status": "draft", "lead_count": 0, "queued_count": 0, "sent_count": 0, "replied_count": 0, "positive_reply_count": 0, "bounced_count": 0, "step_count": 0, "inbox_count": 0, "daily_limit": 40, "default_timezone": "Europe/Berlin", "created_at": "2026-10-07T09:00:00+00:00", "updated_at": "2026-10-07T09:00:00+00:00", "url": "https://app.argorant.com/campaigns/7f3a2c1e-9b4d-4e8a-a1c2-5d6e7f8a9b0c" }, "next": "Add emails (POST /emails), leads (POST /leads) and senders (POST /senders), then POST /launch." } ``` It can answer with these errors (status and code): 400 invalid_request; 401 unauthorized; 403 scope_missing; 409 idempotency_conflict; 422 validation_error; 429 rate_limited. ### Get a campaign `GET /api/v1/campaigns/{campaign_id}` The campaign with its settings, emails, senders, follow-up sequences, personal-line setup and `launch_blockers`: what still has to happen before a launch is accepted. `variable_coverage` lists every variable the emails use with the number of people who have no value for it (`missing`). Those people wait at that email until the value exists or the variable gets a default, such as {{company_normalized|your team}}. A variable that nobody has blocks the launch. | Cost | What it does | Key scopes | | --- | --- | --- | | Free | Reads only | argorant:read_counts | Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `campaign_id` | path | string | yes | The campaign id from create or list. | Example request ```bash curl -X GET "https://app.argorant.com/api/v1/campaigns/7f3a2c1e-9b4d-4e8a-a1c2-5d6e7f8a9b0c" \ -H "Authorization: Bearer $ARGORANT_API_KEY" ``` Example answer (200) ```json { "campaign": { "id": "7f3a2c1e-9b4d-4e8a-a1c2-5d6e7f8a9b0c", "name": "Q4 CFO outreach", "status": "draft", "lead_count": 1188, "queued_count": 0, "sent_count": 0, "replied_count": 0, "positive_reply_count": 0, "bounced_count": 0, "step_count": 0, "inbox_count": 2, "daily_limit": 40, "default_timezone": "Europe/Berlin", "created_at": "2026-10-07T09:00:00+00:00", "updated_at": "2026-10-07T09:00:00+00:00", "url": "https://app.argorant.com/campaigns/7f3a2c1e-9b4d-4e8a-a1c2-5d6e7f8a9b0c" }, "launch_blockers": [], "copy_warnings": [], "emails": [ { "step": 1, "subject": "Quick question, {{first_name}}", "body": "Hi {{first_name}}, ...", "delay_days": 0, "same_thread": false }, { "step": 2, "subject": "Re: Quick question, {{first_name}}", "body": "Bumping this.", "delay_days": 3, "same_thread": true } ], "senders": [ { "email": "elena@northgate-advisory.com", "provider": "google", "status": "connected", "health": "healthy" } ], "subsequences": [] } ``` It can answer with these errors (status and code): 401 unauthorized; 403 scope_missing; 404 not_found; 429 rate_limited. ### Update campaign settings `PATCH /api/v1/campaigns/{campaign_id}` Changes only the fields you send. Same fields as create. Campaigns send plain text; `plain_text: false` is refused. | Cost | What it does | Key scopes | | --- | --- | --- | | Free | writes | argorant:manage_lists | Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `campaign_id` | path | string | yes | The campaign id from create or list. | | `Idempotency-Key` | header | string | no | Any unique text up to 128 characters. A retry with the same key and the same body within 24 hours returns the first answer (with the header Idempotent-Replayed: true) instead of doing the work twice. The same key with another body answers 409 idempotency_conflict. | Body fields (JSON) | Field | Type | Required | Description | | --- | --- | --- | --- | | `name` | string | no | New name. | | `daily_limit` | integer | no | Emails a day for the whole campaign. | | `include_unsubscribe` | boolean | no | Add or remove the opt-out line. | | `window_start` | string | no | HH:MM. | | `window_end` | string | no | HH:MM. | Example request ```bash curl -X PATCH "https://app.argorant.com/api/v1/campaigns/7f3a2c1e-9b4d-4e8a-a1c2-5d6e7f8a9b0c" \ -H "Authorization: Bearer $ARGORANT_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{"daily_limit":60,"window_start":"09:00"}' ``` Example answer (200) ```json { "campaign": { "id": "7f3a2c1e-9b4d-4e8a-a1c2-5d6e7f8a9b0c", "name": "Q4 CFO outreach", "status": "draft", "lead_count": 0, "queued_count": 0, "sent_count": 0, "replied_count": 0, "positive_reply_count": 0, "bounced_count": 0, "step_count": 0, "inbox_count": 0, "daily_limit": 60, "default_timezone": "Europe/Berlin", "created_at": "2026-10-07T09:00:00+00:00", "updated_at": "2026-10-07T09:00:00+00:00", "url": "https://app.argorant.com/campaigns/7f3a2c1e-9b4d-4e8a-a1c2-5d6e7f8a9b0c", "settings": { "daily_limit": 60, "window_start": "09:00", "window_end": "17:00", "timezone": "Europe/Berlin", "include_unsubscribe": false } }, "changed": [ "daily_limit", "sending_window_start" ] } ``` It can answer with these errors (status and code): 401 unauthorized; 403 scope_missing; 404 not_found; 409 idempotency_conflict; 422 validation_error; 429 rate_limited. ### Delete a campaign `DELETE /api/v1/campaigns/{campaign_id}` Deletes a draft, paused or stopped campaign with its emails, people and results. Stop a running campaign first. | Cost | What it does | Key scopes | | --- | --- | --- | | Free | writes | argorant:manage_lists | Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `campaign_id` | path | string | yes | The campaign id from create or list. | | `Idempotency-Key` | header | string | no | Any unique text up to 128 characters. A retry with the same key and the same body within 24 hours returns the first answer (with the header Idempotent-Replayed: true) instead of doing the work twice. The same key with another body answers 409 idempotency_conflict. | Example request ```bash curl -X DELETE "https://app.argorant.com/api/v1/campaigns/7f3a2c1e-9b4d-4e8a-a1c2-5d6e7f8a9b0c" \ -H "Authorization: Bearer $ARGORANT_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" ``` Example answer (200) ```json { "ok": true, "deleted": "7f3a2c1e-9b4d-4e8a-a1c2-5d6e7f8a9b0c" } ``` It can answer with these errors (status and code): 401 unauthorized; 403 scope_missing; 404 not_found; 409 conflict, idempotency_conflict; 429 rate_limited. ### Write the emails `POST /api/v1/campaigns/{campaign_id}/emails` Replaces the sequence. The first email needs a subject. Follow-ups stay in the same thread by default and wait `delay_days` after the previous email. Use {{first_name}}, {{last_name}}, {{company}}, {{company_normalized}} (the name people say), {{title}} and any column you sent with the people, such as {{city}}. A person without a value for a variable never gets the email with a blank. That person waits at that email (status pending, with a `hold`) until the value exists. Give a variable a default for people without one: {{company_normalized|your team}} sends the value, or the words "your team" when there is none, and {{city|}} sends nothing in its place. A default is one plain line of up to 80 characters, without braces or a second `|`. `variable_coverage` in the answer counts, per variable, the people without a value. Write {a|b} to vary a phrase per person. Leftover placeholders such as [link] or TBD come back in `warnings`, and a launch waits until they are gone. `variants` adds other versions of an email, sent in turn. | Cost | What it does | Key scopes | | --- | --- | --- | | Free | writes | argorant:manage_lists | Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `campaign_id` | path | string | yes | The campaign id from create or list. | | `Idempotency-Key` | header | string | no | Any unique text up to 128 characters. A retry with the same key and the same body within 24 hours returns the first answer (with the header Idempotent-Replayed: true) instead of doing the work twice. The same key with another body answers 409 idempotency_conflict. | Body fields (JSON) | Field | Type | Required | Description | | --- | --- | --- | --- | | `emails` | array of object | yes | The emails in order. | | `allow_placeholders` | boolean | no | Save placeholders as written. Only when the user wants them sent like that. | Example request ```bash curl -X POST "https://app.argorant.com/api/v1/campaigns/7f3a2c1e-9b4d-4e8a-a1c2-5d6e7f8a9b0c/emails" \ -H "Authorization: Bearer $ARGORANT_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{"emails":[{"subject":"Quick question, {{first_name}}","body":"Hi {{first_name}},\n\nsaw {{company_normalized}} is hiring in finance. Worth a 10 minute call?\n\nBest"},{"body":"Bumping this up in case it got buried.","delay_days":3,"same_thread":true}]}' ``` Example answer (200) ```json { "emails": [ { "step": 1, "subject": "Quick question, {{first_name}}", "delay_days": 0, "variants": 1 }, { "step": 2, "subject": "Re: Quick question, {{first_name}}", "delay_days": 3, "variants": 1 } ] } ``` It can answer with these errors (status and code): 400 invalid_request; 401 unauthorized; 403 scope_missing; 404 not_found; 409 conflict, idempotency_conflict; 422 validation_error; 429 rate_limited. ### List the people in a campaign `GET /api/v1/campaigns/{campaign_id}/leads` The people in a campaign with where each one is: pending (being checked), queued, active, replied, bounced, completed or suppressed. `status=held` lists the people waiting at an email because a variable it uses has no value for them; each one carries `hold` with the variables, the email and a sentence. | Cost | What it does | Key scopes | | --- | --- | --- | | Free | Reads only | argorant:read_counts | Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `campaign_id` | path | string | yes | The campaign id from create or list. | | `status` | query | string | no | Only this status. One of pending, queued, active, replied, bounced, completed, suppressed, held. | | `q` | query | string | no | Search name, email or company. | | `limit` | query | integer | no | Rows per page, 1 to 500 (default 50). | | `cursor` | query | string | no | The next_cursor of the previous page. Leave out for the first page. | | `offset` | query | integer | no | Rows to skip, as an alternative to cursor. | Example request ```bash curl -X GET "https://app.argorant.com/api/v1/campaigns/7f3a2c1e-9b4d-4e8a-a1c2-5d6e7f8a9b0c/leads?limit=50" \ -H "Authorization: Bearer $ARGORANT_API_KEY" ``` Example answer (200) ```json { "leads": [ { "id": "0c9d8e7f-6a5b-4c3d-8e2f-1a0b9c8d7e6f", "email": "jane.doe@example-acme.com", "first_name": "Jane", "last_name": "Doe", "company": "Acme", "title": "CFO", "status": "replied", "current_step": 2, "next_send_at": null, "email_grade": "valid" } ], "total": 1188, "limit": 50, "offset": 0, "next_cursor": "eyJvIjo1MH0", "has_more": true } ``` It can answer with these errors (status and code): 401 unauthorized; 403 scope_missing; 404 not_found; 422 validation_error; 429 rate_limited. ### Add people `POST /api/v1/campaigns/{campaign_id}/leads` Adds a saved list (`list_id`) or your own `rows`. Every address is checked before it joins. When a source holds anything besides confirmed addresses and you did not say which to take, the answer is `needs_choice` with the count per result and adds nothing yet: ask the user, then call again with `grades: ["valid"]` (recommended) or `["valid", "catch_all"]`. Invalid addresses never join. People from Argorant's data cost 1 credit each the first time; your own rows, repeats and people you already unlocked are free. Any extra key on a row, such as plan or city, becomes a variable like {{plan}}. Private addresses (free mail, home internet) are added like any other unless you send `exclude_private_emails: true` (business emails only); the answer then says how many were left out (`skipped_private_email`). | Cost | What it does | Key scopes | | --- | --- | --- | | 1 credit per new person from Argorant's data; your own rows, repeats and already unlocked people are free | spends credits | argorant:manage_lists | Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `campaign_id` | path | string | yes | The campaign id from create or list. | | `Idempotency-Key` | header | string | no | Any unique text up to 128 characters. A retry with the same key and the same body within 24 hours returns the first answer (with the header Idempotent-Replayed: true) instead of doing the work twice. The same key with another body answers 409 idempotency_conflict. | Body fields (JSON) | Field | Type | Required | Description | | --- | --- | --- | --- | | `list_id` | integer | no | A saved list to enroll. | | `rows` | array of object | no | Your own people, each with an email and any of first_name, last_name, company, title and your own columns. | | `grades` | array of string | no | The results to take, valid alone or valid and catch_all. | | `exclude_private_emails` | boolean | no | Leave out free mail and home internet addresses (business emails only). Default false. | Example request ```bash curl -X POST "https://app.argorant.com/api/v1/campaigns/7f3a2c1e-9b4d-4e8a-a1c2-5d6e7f8a9b0c/leads" \ -H "Authorization: Bearer $ARGORANT_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{"list_id":312,"grades":["valid"]}' ``` Example answer (200) ```json { "needs_choice": true, "added": 0, "question": "Add only the 1,188 valid addresses (recommended)? Or also 28 catch-all, at a higher bounce risk?", "recommended": [ "valid" ], "options": [ { "grade": "valid", "label": "Valid", "count": 1188, "recommended": true }, { "grade": "catch_all", "label": "Catch-all", "count": 28, "recommended": false } ] } ``` It can answer with these errors (status and code): 401 unauthorized; 402 insufficient_credits; 403 scope_missing; 404 not_found; 409 idempotency_conflict; 422 validation_error; 429 rate_limited. ### Remove a person `DELETE /api/v1/campaigns/{campaign_id}/leads/{email}` Takes one person out of the campaign. Nothing more is sent to them from it. | Cost | What it does | Key scopes | | --- | --- | --- | | Free | writes | argorant:manage_lists | Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `campaign_id` | path | string | yes | The campaign id from create or list. | | `email` | path | string | yes | The person's email. | | `Idempotency-Key` | header | string | no | Any unique text up to 128 characters. A retry with the same key and the same body within 24 hours returns the first answer (with the header Idempotent-Replayed: true) instead of doing the work twice. The same key with another body answers 409 idempotency_conflict. | Example request ```bash curl -X DELETE "https://app.argorant.com/api/v1/campaigns/7f3a2c1e-9b4d-4e8a-a1c2-5d6e7f8a9b0c/leads/jane.doe%40example-acme.com" \ -H "Authorization: Bearer $ARGORANT_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" ``` Example answer (200) ```json { "ok": true, "removed": "jane.doe@example-acme.com" } ``` It can answer with these errors (status and code): 401 unauthorized; 403 scope_missing; 404 not_found; 409 idempotency_conflict; 429 rate_limited. ### Remove many people `POST /api/v1/campaigns/{campaign_id}/leads/remove` Takes many people out of a campaign, chosen by status, replied, bounced, email domain, tag, ids, addresses or a saved list. Send `preview: true` first to see how many would go. People who already got an email stay unless you send `include_contacted: true`; their sent emails and replies stay in the numbers. A large removal runs in the background and answers 202 with a job to follow at its `status_url`. | Cost | What it does | Key scopes | | --- | --- | --- | | Free | writes | argorant:manage_lists | Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `campaign_id` | path | string | yes | The campaign id from create or list. | | `Idempotency-Key` | header | string | no | Any unique text up to 128 characters. A retry with the same key and the same body within 24 hours returns the first answer (with the header Idempotent-Replayed: true) instead of doing the work twice. The same key with another body answers 409 idempotency_conflict. | Body fields (JSON) | Field | Type | Required | Description | | --- | --- | --- | --- | | `status` | array of string | no | One or more lead statuses, from pending, queued, active, sent, replied, bounced, unsubscribed, failed or completed. | | `replied` | boolean | no | true for only the people who replied, false for only the ones who did not. | | `bounced` | boolean | no | true for only the bounced addresses, false for only the others. | | `domains` | array of string | no | Email domains of the people. | | `tag` | string | no | A tag the people carry. | | `lead_ids` | array of string | no | Ids from GET .../leads. | | `emails` | array of string | no | The people's addresses. | | `list_id` | integer | no | Everyone of this saved list. | | `include_contacted` | boolean | no | Also stop people who already got an email and wait for a follow-up. | | `preview` | boolean | no | true only counts and changes nothing. | Example request ```bash curl -X POST "https://app.argorant.com/api/v1/campaigns/7f3a2c1e-9b4d-4e8a-a1c2-5d6e7f8a9b0c/leads/remove" \ -H "Authorization: Bearer $ARGORANT_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{"replied":false,"status":["queued","pending"],"preview":true}' ``` Example answer (200) ```json { "matched": 412, "would_remove": 380, "never_emailed": 380, "already_emailed_still_in_sequence": 32, "already_emailed_finished": 0, "kept_because_already_emailed": 32, "include_contacted": false, "preview": true, "removed": 0, "summary": "380 people would be taken out of the campaign. 32 who already got an email stay, because they were not asked for (include_contacted=true takes out the ones still waiting for a follow-up). Nothing was changed yet." } ``` It can answer with these errors (status and code): 401 unauthorized; 403 scope_missing; 404 not_found; 409 idempotency_conflict; 422 validation_error; 429 rate_limited. ### Background jobs for people `GET /api/v1/campaigns/{campaign_id}/lead-jobs` The latest large adds, removals and personal-line files of this campaign that run in the background, newest first (up to 10). | Cost | What it does | Key scopes | | --- | --- | --- | | Free | Reads only | argorant:read_counts | Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `campaign_id` | path | string | yes | The campaign id from create or list. | Example request ```bash curl -X GET "https://app.argorant.com/api/v1/campaigns/7f3a2c1e-9b4d-4e8a-a1c2-5d6e7f8a9b0c/lead-jobs" \ -H "Authorization: Bearer $ARGORANT_API_KEY" ``` Example answer (200) ```json { "jobs": [ { "job_id": "4b1d2c3e-5f60-4a7b-8c9d-0e1f2a3b4c5d", "status": "running", "kind": "remove", "people_selected": 12840, "created_at": "2026-10-20T09:00:00+00:00", "started_at": "2026-10-20T09:00:02+00:00", "finished_at": null, "status_url": "/api/v1/campaigns/7f3a2c1e-9b4d-4e8a-a1c2-5d6e7f8a9b0c/lead-jobs/4b1d2c3e-5f60-4a7b-8c9d-0e1f2a3b4c5d", "summary": "Taking 12,840 people out of the campaign in the background. Check again in a minute with this job_id.", "poll_after_seconds": 30 } ] } ``` It can answer with these errors (status and code): 401 unauthorized; 403 scope_missing; 404 not_found; 429 rate_limited. ### One background job `GET /api/v1/campaigns/{campaign_id}/lead-jobs/{job_id}` How far a large add, removal or personal-line file has come. While it runs, ask again after `poll_after_seconds`. When it is done, `result` holds the counts. | Cost | What it does | Key scopes | | --- | --- | --- | | Free | Reads only | argorant:read_counts | Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `campaign_id` | path | string | yes | The campaign id from create or list. | | `job_id` | path | string | yes | The job id from the 202 answer. | Example request ```bash curl -X GET "https://app.argorant.com/api/v1/campaigns/7f3a2c1e-9b4d-4e8a-a1c2-5d6e7f8a9b0c/lead-jobs/4b1d2c3e-5f60-4a7b-8c9d-0e1f2a3b4c5d" \ -H "Authorization: Bearer $ARGORANT_API_KEY" ``` Example answer (200) ```json { "job_id": "4b1d2c3e-5f60-4a7b-8c9d-0e1f2a3b4c5d", "status": "done", "kind": "remove", "people_selected": 12840, "created_at": "2026-10-20T09:00:00+00:00", "started_at": "2026-10-20T09:00:02+00:00", "finished_at": "2026-10-20T09:01:40+00:00", "status_url": "/api/v1/campaigns/7f3a2c1e-9b4d-4e8a-a1c2-5d6e7f8a9b0c/lead-jobs/4b1d2c3e-5f60-4a7b-8c9d-0e1f2a3b4c5d", "summary": "Took 12,840 people out of the campaign. Their sent emails and replies stay in the numbers.", "poll_after_seconds": 30, "result": { "removed": 12840, "summary": "Took 12,840 people out of the campaign. Their sent emails and replies stay in the numbers." } } ``` It can answer with these errors (status and code): 401 unauthorized; 403 scope_missing; 404 not_found; 429 rate_limited. ### Write personal lines `PATCH /api/v1/campaigns/{campaign_id}/leads/custom-fields` Saves the personal lines your assistant wrote, for up to 5,000 people per call (fewer is fine). A finished file with more goes through POST .../leads/custom-fields/import. Set up the campaign's personal-line variables first (PUT .../personalization). Send `leads` as a list of `{lead_id or email, values: {custom_x: "..."}}`; a person you checked and found nothing for can keep the fallback with `keep_fallback: true`. Each line is one plain line within the variable's `max_length` (20 to 300 characters, 150 by default), and `basis` is up to 200 characters. A line a person already has is never replaced by accident. Without `overwrite` it stays, and the answer lists it in `kept_existing` with the saved and the sent text. To correct lines, send them again with `overwrite: true`. To clear a line, send the variable as `null` (or an empty text) with `overwrite: true`; the person gets the fallback again and, with no line left, is back in the list of people still to write. Every replaced or cleared line is kept as a record, old and new, and the answer lists them in `changes`. Sending the same line again changes nothing (`unchanged`). Up to 300 calls an hour per workspace. | Cost | What it does | Key scopes | | --- | --- | --- | | Free | writes | argorant:manage_lists | Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `campaign_id` | path | string | yes | The campaign id from create or list. | | `Idempotency-Key` | header | string | no | Any unique text up to 128 characters. A retry with the same key and the same body within 24 hours returns the first answer (with the header Idempotent-Replayed: true) instead of doing the work twice. The same key with another body answers 409 idempotency_conflict. | Body fields (JSON) | Field | Type | Required | Description | | --- | --- | --- | --- | | `leads` | array of object | yes | 1 to 5,000 people with their lines. | | `overwrite` | boolean | no | true replaces or clears lines people already have. Leave it out (false) so a saved line is never replaced by accident. Also accepted as the query parameter ?overwrite=true. | Example request ```bash curl -X PATCH "https://app.argorant.com/api/v1/campaigns/7f3a2c1e-9b4d-4e8a-a1c2-5d6e7f8a9b0c/leads/custom-fields" \ -H "Authorization: Bearer $ARGORANT_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{"leads":[{"email":"jane.doe@example-acme.com","values":{"custom_opener":"Congrats on the new Munich office."}}]}' ``` Example answer (200) ```json { "saved": 1, "kept_fallback": 0, "values_saved": 1, "unchanged": 0, "changed": 0, "cleared": 0, "kept_existing_count": 1, "kept_existing": [ { "lead_id": "0c9d8e7f-6a5b-4c3d-8e2f-1a0b9c8d7e6f", "name": "custom_opener", "saved": "Congrats on the Munich office.", "sent": "Congrats on the new Munich office." } ], "changes": [], "overwrite": false, "rejected_count": 0, "rejected": [], "not_found_count": 0, "not_found": [], "progress": { "total": 1188, "written": 413, "fallback": 775 }, "summary": "Saved lines for 1 contact. 1 contact already has a saved line that was kept (see kept_existing). To replace or clear saved lines, send them again with overwrite: true." } ``` It can answer with these errors (status and code): 400 invalid_request; 401 unauthorized; 403 scope_missing; 404 not_found; 409 conflict, idempotency_conflict; 422 validation_error; 429 rate_limited. ### Personal lines from a file `POST /api/v1/campaigns/{campaign_id}/leads/custom-fields/import` Send a finished file of personal lines in one go: CSV (header `email` or `lead_id`, then one column per {{custom_...}} variable, optional `basis`, `keep_fallback` and `clear`), JSON (`[{email or lead_id, values: {...}}]` or `{"leads": [...], "overwrite": true}`) or NDJSON, up to 200,000 rows and 50 MB. Send the file as the body with Content-Type text/csv, application/json or application/x-ndjson, or as multipart form data in a `file` field. Every row gets the same checks as a single call. Rows that fail are listed by row number and never stop the rest. Up to 5,000 rows are written at once; a bigger file answers with a job to follow. Up to 30 files an hour per workspace. A line a person already has is kept unless you send `overwrite=true` (query parameter, a form field, or `overwrite` in the JSON object). Kept lines are listed in `kept_existing` with their row. With overwrite, replaced lines are counted in `changed` and kept as a record, old and new. To clear lines with overwrite, name the variables in the CSV `clear` column (several separated by spaces, or `all`), or send them as `null` in JSON. An empty CSV cell never clears anything. The same file with and without overwrite are two separate uploads. | Cost | What it does | Key scopes | | --- | --- | --- | | Free | writes | argorant:manage_lists | Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `campaign_id` | path | string | yes | The campaign id from create or list. | | `overwrite` | query | boolean | no | true replaces or clears lines people already have (default false: they are kept and listed). | | `Idempotency-Key` | header | string | no | Any unique text up to 128 characters. A retry with the same key and the same body within 24 hours returns the first answer (with the header Idempotent-Replayed: true) instead of doing the work twice. The same key with another body answers 409 idempotency_conflict. | Body fields (JSON) | Field | Type | Required | Description | | --- | --- | --- | --- | | `leads` | array of object | no | The people with their lines, when you send JSON. CSV and NDJSON go as the raw body instead. | | `overwrite` | boolean | no | In a JSON object, the same as the query parameter. | Example request ```bash curl -X POST "https://app.argorant.com/api/v1/campaigns/7f3a2c1e-9b4d-4e8a-a1c2-5d6e7f8a9b0c/leads/custom-fields/import" \ -H "Authorization: Bearer $ARGORANT_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{"leads":[{"email":"jane.doe@example-acme.com","values":{"custom_opener":"Congrats on the new Munich office."}}]}' ``` Example answer (200) ```json { "format": "json", "total_rows": 1, "valid_rows": 1, "invalid_count": 0, "invalid": [], "status": "done", "overwrite": false, "written": 1, "kept_fallback": 0, "unchanged": 0, "duplicates": 0, "changed": 0, "cleared": 0, "kept_existing_count": 0, "kept_existing": [], "not_found_count": 0, "not_found": [], "summary": "Saved lines for 1 contact." } ``` It can answer with these errors (status and code): 401 unauthorized; 403 scope_missing; 404 not_found; 409 conflict, idempotency_conflict; 422 validation_error; 429 rate_limited. ### Personal lines file status `GET /api/v1/campaigns/{campaign_id}/leads/custom-fields/import/{job_id}` How far a large file of personal lines has come, and the counts when it is done: lines saved, people who keep the fallback, lines kept because the person already had one (`kept_existing`, with the row), and with overwrite the lines replaced (`changed`) and cleared. | Cost | What it does | Key scopes | | --- | --- | --- | | Free | Reads only | argorant:read_counts | Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `campaign_id` | path | string | yes | The campaign id from create or list. | | `job_id` | path | string | yes | The job id from the import answer. | Example request ```bash curl -X GET "https://app.argorant.com/api/v1/campaigns/7f3a2c1e-9b4d-4e8a-a1c2-5d6e7f8a9b0c/leads/custom-fields/import/6c5b4a39-2817-4f6e-9d5c-4b3a29180f7e" \ -H "Authorization: Bearer $ARGORANT_API_KEY" ``` Example answer (200) ```json { "job_id": "6c5b4a39-2817-4f6e-9d5c-4b3a29180f7e", "status": "done", "overwrite": false, "total_rows": 48000, "valid_rows": 47990, "processed_rows": 47990, "written": 46012, "kept_fallback": 978, "unchanged": 0, "duplicates": 0, "changed": 0, "cleared": 0, "kept_existing_count": 1000, "kept_existing": [ { "row": 12, "lead_id": "0c9d8e7f-6a5b-4c3d-8e2f-1a0b9c8d7e6f", "name": "custom_opener", "saved": "Congrats on the Munich office.", "sent": "Congrats on the new Munich office." } ], "invalid_count": 10, "summary": "Saved lines for 46,012 contacts. 1,000 contacts already have a saved line that was kept (see kept_existing). To replace or clear saved lines, send them again with overwrite: true." } ``` It can answer with these errors (status and code): 401 unauthorized; 403 scope_missing; 404 not_found; 429 rate_limited. ### Read the personal lines `GET /api/v1/campaigns/{campaign_id}/personalization` The campaign's personal-line variables, how many people have their own line, and the people who still use the fallback, the ones sent first first, with facts about their company to write from. Page through all of them with `cursor`. A person whose company has no description yet carries `description_status: "pending"`: Argorant is reading the company website, so write that line after the next call, not from keywords alone (`descriptions_pending` counts them). `"unavailable"` means the website gave nothing usable. `limits` lists every limit of personal lines: variables per campaign, instruction and line length, people per call and per page, file size, and calls per hour. | Cost | What it does | Key scopes | | --- | --- | --- | | Free | Reads only | argorant:read_counts | Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `campaign_id` | path | string | yes | The campaign id from create or list. | | `pending_limit` | query | integer | no | People still on the fallback to return, 0 to 5,000 (default 25). With company facts, 100 to 200 at a time is easier to work with. | | `cursor` | query | string | no | The next_cursor of the answer before: continues after its last person, in the same order. | | `pending_offset` | query | integer | no | Skip this many of them (the cursor is better for long lists). | | `include_facts` | query | boolean | no | Add company facts (default true). | Example request ```bash curl -X GET "https://app.argorant.com/api/v1/campaigns/7f3a2c1e-9b4d-4e8a-a1c2-5d6e7f8a9b0c/personalization" \ -H "Authorization: Bearer $ARGORANT_API_KEY" ``` Example answer (200) ```json { "campaign_id": "7f3a2c1e-9b4d-4e8a-a1c2-5d6e7f8a9b0c", "configured": true, "personalization": { "variables": [ { "name": "custom_opener", "instruction": "One sentence about something recent at their company.", "fallback": "Hope the quarter is going well.", "max_length": 150, "case": "auto", "case_in_use": "as_is" } ] }, "progress": { "total": 1188, "written": 412, "fallback": 776 }, "pending_leads": [ { "lead_id": "0c9d8e7f-6a5b-4c3d-8e2f-1a0b9c8d7e6f", "email": "jane.doe@example-acme.com", "company": "Acme", "facts": { "industry": "Manufacturing", "city": "Munich" } } ], "next_cursor": "WyIiLCIyMDI2LTEwLTIxVDA5OjAwOjAwKzAwOjAwIiwiMGM5ZDhlN2YiXQ", "summary": "412 of 1,188 contacts have their own line; the rest send with the fallback.", "limits": { "variables_per_campaign": 5, "instruction_characters": 4000, "line_characters": { "min": 20, "max": 300, "default": 150 }, "template_characters": 10000, "basis_characters": 200, "contacts_per_call": 5000, "contacts_per_status_page": 5000, "file_rows": 200000, "file_megabytes": 50, "file_rows_written_at_once": 5000, "calls_per_hour": { "setup": 30, "write": 300, "status": 300, "file": 30 ... ``` It can answer with these errors (status and code): 401 unauthorized; 403 scope_missing; 404 not_found; 422 validation_error; 429 rate_limited. ### Set up personal lines `PUT /api/v1/campaigns/{campaign_id}/personalization` Sets the campaign's personal-line variables, each with a name, an instruction for the writer and a fallback that reads well for anyone. Put {{custom_name}} into the emails where the line goes. Everyone without their own line gets the fallback at once, so the campaign can launch at any time. The limits are 1 to 5 variables per campaign, an instruction of up to 4,000 characters, 20 to 300 characters per line (`max_length`, 150 by default; the fallback counts too) and a template of up to 10,000 characters. Up to 30 setups an hour per workspace. A line used in the middle of a sentence is saved with a lowercase first letter ("Hiring managers at" becomes "hiring managers at"), while acronyms, names, brands and places (CFOs, AWS, Chicago) stay as written. That is `case: "auto"`, the default: it follows where your emails use the variable, and a line that starts a sentence keeps its first letter. `sentence_middle` lowercases wherever the variable is used, `as_is` keeps every line exactly as written. Saving brings lines already saved to the case in use; `case_in_use` in the answer shows it per variable. The fallback is always kept as you wrote it. | Cost | What it does | Key scopes | | --- | --- | --- | | Free | writes | argorant:manage_lists | Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `campaign_id` | path | string | yes | The campaign id from create or list. | | `Idempotency-Key` | header | string | no | Any unique text up to 128 characters. A retry with the same key and the same body within 24 hours returns the first answer (with the header Idempotent-Replayed: true) instead of doing the work twice. The same key with another body answers 409 idempotency_conflict. | Body fields (JSON) | Field | Type | Required | Description | | --- | --- | --- | --- | | `variables` | array of object | yes | 1 to 5 variables. | | `template` | string | no | The email text the lines go into, up to 10,000 characters (optional; helps whoever writes the lines). | | `allow_links` | boolean | no | Allow links inside the lines (default false). | Example request ```bash curl -X PUT "https://app.argorant.com/api/v1/campaigns/7f3a2c1e-9b4d-4e8a-a1c2-5d6e7f8a9b0c/personalization" \ -H "Authorization: Bearer $ARGORANT_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{"variables":[{"name":"opener","instruction":"One sentence about something recent at their company.","fallback":"Hope the quarter is going well."},{"name":"buyers","instruction":"Who they sell to, 4 to 10 words, e.g. '\''restaurants that need payroll help'\''.","fallback":"businesses like yours","max_length":120,"case":"sentence_middle"}]}' ``` Example answer (200) ```json { "campaign_id": "7f3a2c1e-9b4d-4e8a-a1c2-5d6e7f8a9b0c", "personalization": { "variables": [ { "name": "custom_opener" } ] }, "progress": { "total": 1188, "written": 0, "fallback": 1188 }, "notes": [ "Renamed to the custom_ form: opener -> custom_opener. Use these names in the emails, e.g. {{custom_opener}}." ], "fallbacks_written": 1188, "summary": "Saved 1 variable: {{custom_opener}}. Put it in the emails where the line goes.", "limits": { "variables_per_campaign": 5, "instruction_characters": 4000, "line_characters": { "min": 20, "max": 300, "default": 150 }, "template_characters": 10000, "basis_characters": 200, "contacts_per_call": 5000, "contacts_per_status_page": 5000, "file_rows": 200000, "file_megabytes": 50, "file_rows_written_at_once": 5000, "calls_per_hour": { "setup": 30, "write": 300, "status": 300, "file": 30 } } } ``` It can answer with these errors (status and code): 400 invalid_request; 401 unauthorized; 403 scope_missing; 404 not_found; 409 idempotency_conflict; 422 validation_error; 429 rate_limited. ### List a campaign's senders `GET /api/v1/campaigns/{campaign_id}/senders` The mailboxes that send this campaign, a page at a time. Narrow by domain or status. The first page also has `summary`: the counts by domain and by status. | Cost | What it does | Key scopes | | --- | --- | --- | | Free | Reads only | argorant:read_counts | Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `campaign_id` | path | string | yes | The campaign id from create or list. | | `limit` | query | integer | no | Rows per page, 1 to 500 (default 50). | | `cursor` | query | string | no | The next_cursor of the previous page. Leave out for the first page. | | `domain` | query | string | no | One domain, or several separated by commas. | | `status` | query | string | no | sendable, warming, not_connected, needs_attention or paused; several separated by commas. | Example request ```bash curl -X GET "https://app.argorant.com/api/v1/campaigns/7f3a2c1e-9b4d-4e8a-a1c2-5d6e7f8a9b0c/senders?limit=50" \ -H "Authorization: Bearer $ARGORANT_API_KEY" ``` Example answer (200) ```json { "senders": [ { "email": "elena@northgate-advisory.com", "name": "Elena Vaughn", "domain": "northgate-advisory.com", "status": "sendable", "daily_limit": 40, "sent_today": 12 } ], "total": 1, "next_cursor": null, "has_more": false, "summary": { "total": 1, "by_status": { "sendable": 1 }, "by_domain": [ { "domain": "northgate-advisory.com", "total": 1, "by_status": { "sendable": 1 } } ] } } ``` It can answer with these errors (status and code): 401 unauthorized; 403 scope_missing; 404 not_found; 422 validation_error; 429 rate_limited. ### Choose the sending mailboxes `POST /api/v1/campaigns/{campaign_id}/senders` Attaches connected mailboxes by address, or every connected mailbox with `all_connected: true`. Emails are spread across them within each mailbox's daily limit. | Cost | What it does | Key scopes | | --- | --- | --- | | Free | writes | argorant:manage_lists | Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `campaign_id` | path | string | yes | The campaign id from create or list. | | `Idempotency-Key` | header | string | no | Any unique text up to 128 characters. A retry with the same key and the same body within 24 hours returns the first answer (with the header Idempotent-Replayed: true) instead of doing the work twice. The same key with another body answers 409 idempotency_conflict. | Body fields (JSON) | Field | Type | Required | Description | | --- | --- | --- | --- | | `emails` | array of string | no | Mailbox addresses. | | `all_connected` | boolean | no | Attach every connected mailbox. | Example request ```bash curl -X POST "https://app.argorant.com/api/v1/campaigns/7f3a2c1e-9b4d-4e8a-a1c2-5d6e7f8a9b0c/senders" \ -H "Authorization: Bearer $ARGORANT_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{"emails":["elena@northgate-advisory.com","marina@northgate-partners.co"]}' ``` Example answer (200) ```json { "attached": 2, "senders": [ "elena@northgate-advisory.com", "marina@northgate-partners.co" ] } ``` It can answer with these errors (status and code): 400 invalid_request; 401 unauthorized; 403 scope_missing; 404 not_found; 409 idempotency_conflict; 422 validation_error; 429 rate_limited. ### Send a test email `POST /api/v1/campaigns/{campaign_id}/test-email` Sends one test of a campaign email to you or to a member of your workspace, filled with a sample contact. Adds nobody to the campaign and changes nothing. A few tests an hour per account. | Cost | What it does | Key scopes | | --- | --- | --- | | Free | sends email | argorant:manage_lists | Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `campaign_id` | path | string | yes | The campaign id from create or list. | | `Idempotency-Key` | header | string | no | Any unique text up to 128 characters. A retry with the same key and the same body within 24 hours returns the first answer (with the header Idempotent-Replayed: true) instead of doing the work twice. The same key with another body answers 409 idempotency_conflict. | Body fields (JSON) | Field | Type | Required | Description | | --- | --- | --- | --- | | `to` | string | no | Leave out to send it to yourself. Otherwise a member of your workspace. | | `step` | integer | no | Which email of the campaign, 1 for the first (default 1). | | `subject` | string | no | Test this subject instead of a campaign email. | | `body` | string | no | Test this text instead of a campaign email. | | `sender` | string | no | A mailbox of your workspace that can send. Leave out to use one of the campaign's senders. | | `sample` | object | no | Fields of a made-up contact, such as first_name and company, to fill the email with. | Example request ```bash curl -X POST "https://app.argorant.com/api/v1/campaigns/7f3a2c1e-9b4d-4e8a-a1c2-5d6e7f8a9b0c/test-email" \ -H "Authorization: Bearer $ARGORANT_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{"step":1}' ``` Example answer (200) ```json { "sent": true, "sent_from": "elena@northgate-advisory.com", "to": "you@northgate-advisory.com", "email": 1, "subject": "Quick question, Jane", "summary": "Sent a test of email 1 from elena@northgate-advisory.com to you@northgate-advisory.com. Nothing was added to the campaign and nothing else was sent." } ``` It can answer with these errors (status and code): 401 unauthorized; 403 scope_missing; 404 not_found; 409 idempotency_conflict; 422 validation_error; 429 rate_limited. ### List folders `GET /api/v1/folders` Your campaign folders with how many campaigns each holds, and how many campaigns are in no folder. | Cost | What it does | Key scopes | | --- | --- | --- | | Free | Reads only | argorant:read_counts | Example request ```bash curl -X GET "https://app.argorant.com/api/v1/folders" \ -H "Authorization: Bearer $ARGORANT_API_KEY" ``` Example answer (200) ```json { "folders": [ { "id": "9d8c7b6a-5e4f-4a3b-8c2d-1e0f9a8b7c6d", "name": "Q4 outreach", "campaigns": 3, "created_at": "2026-10-19T09:00:00+00:00" } ], "campaigns_total": 7, "campaigns_not_in_a_folder": 4 } ``` It can answer with these errors (status and code): 401 unauthorized; 403 scope_missing; 429 rate_limited. ### Create a folder `POST /api/v1/folders` A new folder for campaigns. | Cost | What it does | Key scopes | | --- | --- | --- | | Free | writes | argorant:manage_lists | Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `Idempotency-Key` | header | string | no | Any unique text up to 128 characters. A retry with the same key and the same body within 24 hours returns the first answer (with the header Idempotent-Replayed: true) instead of doing the work twice. The same key with another body answers 409 idempotency_conflict. | Body fields (JSON) | Field | Type | Required | Description | | --- | --- | --- | --- | | `name` | string | yes | The folder's name. | Example request ```bash curl -X POST "https://app.argorant.com/api/v1/folders" \ -H "Authorization: Bearer $ARGORANT_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{"name":"Q4 outreach"}' ``` Example answer (200) ```json { "folder": { "id": "9d8c7b6a-5e4f-4a3b-8c2d-1e0f9a8b7c6d", "name": "Q4 outreach", "campaigns": 0, "created_at": "2026-10-19T09:00:00+00:00" } } ``` It can answer with these errors (status and code): 401 unauthorized; 403 scope_missing; 409 idempotency_conflict; 422 validation_error; 429 rate_limited. ### Rename a folder `PATCH /api/v1/folders/{folder_id}` Gives a folder a new name. Its campaigns stay in it. | Cost | What it does | Key scopes | | --- | --- | --- | | Free | writes | argorant:manage_lists | Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `folder_id` | path | string | yes | The folder id from GET /api/v1/folders. | | `Idempotency-Key` | header | string | no | Any unique text up to 128 characters. A retry with the same key and the same body within 24 hours returns the first answer (with the header Idempotent-Replayed: true) instead of doing the work twice. The same key with another body answers 409 idempotency_conflict. | Body fields (JSON) | Field | Type | Required | Description | | --- | --- | --- | --- | | `name` | string | yes | The new name. | Example request ```bash curl -X PATCH "https://app.argorant.com/api/v1/folders/9d8c7b6a-5e4f-4a3b-8c2d-1e0f9a8b7c6d" \ -H "Authorization: Bearer $ARGORANT_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{"name":"Q4 outreach DACH"}' ``` Example answer (200) ```json { "folder": { "id": "9d8c7b6a-5e4f-4a3b-8c2d-1e0f9a8b7c6d", "name": "Q4 outreach DACH", "campaigns": 3, "created_at": "2026-10-19T09:00:00+00:00" } } ``` It can answer with these errors (status and code): 401 unauthorized; 403 scope_missing; 404 not_found; 409 idempotency_conflict; 422 validation_error; 429 rate_limited. ### Move a campaign to a folder `POST /api/v1/campaigns/{campaign_id}/folder` Files the campaign into a folder. Send `folder_id: null` to take it out of its folder. Sending is not affected. | Cost | What it does | Key scopes | | --- | --- | --- | | Free | writes | argorant:manage_lists | Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `campaign_id` | path | string | yes | The campaign id from create or list. | | `Idempotency-Key` | header | string | no | Any unique text up to 128 characters. A retry with the same key and the same body within 24 hours returns the first answer (with the header Idempotent-Replayed: true) instead of doing the work twice. The same key with another body answers 409 idempotency_conflict. | Body fields (JSON) | Field | Type | Required | Description | | --- | --- | --- | --- | | `folder_id` | string | no | The folder id, or null for no folder. | Example request ```bash curl -X POST "https://app.argorant.com/api/v1/campaigns/7f3a2c1e-9b4d-4e8a-a1c2-5d6e7f8a9b0c/folder" \ -H "Authorization: Bearer $ARGORANT_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{"folder_id":"9d8c7b6a-5e4f-4a3b-8c2d-1e0f9a8b7c6d"}' ``` Example answer (200) ```json { "campaign": { "id": "7f3a2c1e-9b4d-4e8a-a1c2-5d6e7f8a9b0c", "name": "Q4 CFO outreach", "status": "draft", "lead_count": 0, "queued_count": 0, "sent_count": 0, "replied_count": 0, "positive_reply_count": 0, "bounced_count": 0, "step_count": 0, "inbox_count": 0, "daily_limit": 40, "default_timezone": "Europe/Berlin", "created_at": "2026-10-07T09:00:00+00:00", "updated_at": "2026-10-07T09:00:00+00:00", "url": "https://app.argorant.com/campaigns/7f3a2c1e-9b4d-4e8a-a1c2-5d6e7f8a9b0c" } } ``` It can answer with these errors (status and code): 400 invalid_request; 401 unauthorized; 403 scope_missing; 404 not_found; 409 idempotency_conflict; 422 validation_error; 429 rate_limited. ### Remove a sending mailbox `DELETE /api/v1/campaigns/{campaign_id}/senders/{email}` Takes one mailbox off the campaign. It stays connected to your account. | Cost | What it does | Key scopes | | --- | --- | --- | | Free | writes | argorant:manage_lists | Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `campaign_id` | path | string | yes | The campaign id from create or list. | | `email` | path | string | yes | The mailbox address. | | `Idempotency-Key` | header | string | no | Any unique text up to 128 characters. A retry with the same key and the same body within 24 hours returns the first answer (with the header Idempotent-Replayed: true) instead of doing the work twice. The same key with another body answers 409 idempotency_conflict. | Example request ```bash curl -X DELETE "https://app.argorant.com/api/v1/campaigns/7f3a2c1e-9b4d-4e8a-a1c2-5d6e7f8a9b0c/senders/elena%40northgate-advisory.com" \ -H "Authorization: Bearer $ARGORANT_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" ``` Example answer (200) ```json { "ok": true, "detached": "elena@northgate-advisory.com" } ``` It can answer with these errors (status and code): 401 unauthorized; 403 scope_missing; 404 not_found; 409 idempotency_conflict; 429 rate_limited. ### Launch `POST /api/v1/campaigns/{campaign_id}/launch` Starts sending. Launch only after the user said yes. The answer carries `variable_coverage`: people without a value for a variable of the emails wait at that email and never get a blank. Refused with `launch_blocked` and the list of blockers while the campaign has no email, no mailbox with room, no people, or text that would go out as written ([link], TBD). When that text is meant, launch with `allow_placeholders: true`. | Cost | What it does | Key scopes | | --- | --- | --- | | Free; emails count against the plan's monthly campaign email allowance | sends email | argorant:manage_lists | Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `campaign_id` | path | string | yes | The campaign id from create or list. | | `Idempotency-Key` | header | string | no | Any unique text up to 128 characters. A retry with the same key and the same body within 24 hours returns the first answer (with the header Idempotent-Replayed: true) instead of doing the work twice. The same key with another body answers 409 idempotency_conflict. | Body fields (JSON) | Field | Type | Required | Description | | --- | --- | --- | --- | | `allow_placeholders` | boolean | no | Send leftover placeholders as written. Only after the user saw them. | Example request ```bash curl -X POST "https://app.argorant.com/api/v1/campaigns/7f3a2c1e-9b4d-4e8a-a1c2-5d6e7f8a9b0c/launch" \ -H "Authorization: Bearer $ARGORANT_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{}' ``` Example answer (200) ```json { "campaign": { "id": "7f3a2c1e-9b4d-4e8a-a1c2-5d6e7f8a9b0c", "name": "Q4 CFO outreach", "status": "active", "lead_count": 0, "queued_count": 0, "sent_count": 0, "replied_count": 0, "positive_reply_count": 0, "bounced_count": 0, "step_count": 0, "inbox_count": 0, "daily_limit": 40, "default_timezone": "Europe/Berlin", "created_at": "2026-10-07T09:00:00+00:00", "updated_at": "2026-10-07T09:00:00+00:00", "url": "https://app.argorant.com/campaigns/7f3a2c1e-9b4d-4e8a-a1c2-5d6e7f8a9b0c" } } ``` It can answer with these errors (status and code): 400 launch_blocked; 401 unauthorized; 403 scope_missing; 404 not_found; 409 idempotency_conflict; 422 validation_error; 429 rate_limited. ### Pause `POST /api/v1/campaigns/{campaign_id}/pause` Holds sending and keeps the schedule. Launch again to continue. | Cost | What it does | Key scopes | | --- | --- | --- | | Free | writes | argorant:manage_lists | Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `campaign_id` | path | string | yes | The campaign id from create or list. | | `Idempotency-Key` | header | string | no | Any unique text up to 128 characters. A retry with the same key and the same body within 24 hours returns the first answer (with the header Idempotent-Replayed: true) instead of doing the work twice. The same key with another body answers 409 idempotency_conflict. | Example request ```bash curl -X POST "https://app.argorant.com/api/v1/campaigns/7f3a2c1e-9b4d-4e8a-a1c2-5d6e7f8a9b0c/pause" \ -H "Authorization: Bearer $ARGORANT_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{}' ``` Example answer (200) ```json { "campaign": { "id": "7f3a2c1e-9b4d-4e8a-a1c2-5d6e7f8a9b0c", "name": "Q4 CFO outreach", "status": "paused", "lead_count": 0, "queued_count": 0, "sent_count": 0, "replied_count": 0, "positive_reply_count": 0, "bounced_count": 0, "step_count": 0, "inbox_count": 0, "daily_limit": 40, "default_timezone": "Europe/Berlin", "created_at": "2026-10-07T09:00:00+00:00", "updated_at": "2026-10-07T09:00:00+00:00", "url": "https://app.argorant.com/campaigns/7f3a2c1e-9b4d-4e8a-a1c2-5d6e7f8a9b0c" } } ``` It can answer with these errors (status and code): 401 unauthorized; 403 scope_missing; 404 not_found; 409 idempotency_conflict; 429 rate_limited. ### Stop `POST /api/v1/campaigns/{campaign_id}/stop` Ends the campaign for good. Nothing more is sent. | Cost | What it does | Key scopes | | --- | --- | --- | | Free | writes | argorant:manage_lists | Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `campaign_id` | path | string | yes | The campaign id from create or list. | | `Idempotency-Key` | header | string | no | Any unique text up to 128 characters. A retry with the same key and the same body within 24 hours returns the first answer (with the header Idempotent-Replayed: true) instead of doing the work twice. The same key with another body answers 409 idempotency_conflict. | Example request ```bash curl -X POST "https://app.argorant.com/api/v1/campaigns/7f3a2c1e-9b4d-4e8a-a1c2-5d6e7f8a9b0c/stop" \ -H "Authorization: Bearer $ARGORANT_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{}' ``` Example answer (200) ```json { "campaign": { "id": "7f3a2c1e-9b4d-4e8a-a1c2-5d6e7f8a9b0c", "name": "Q4 CFO outreach", "status": "completed", "lead_count": 0, "queued_count": 0, "sent_count": 0, "replied_count": 0, "positive_reply_count": 0, "bounced_count": 0, "step_count": 0, "inbox_count": 0, "daily_limit": 40, "default_timezone": "Europe/Berlin", "created_at": "2026-10-07T09:00:00+00:00", "updated_at": "2026-10-07T09:00:00+00:00", "url": "https://app.argorant.com/campaigns/7f3a2c1e-9b4d-4e8a-a1c2-5d6e7f8a9b0c" } } ``` It can answer with these errors (status and code): 401 unauthorized; 403 scope_missing; 404 not_found; 409 idempotency_conflict; 429 rate_limited. ### Campaign results `GET /api/v1/campaigns/{campaign_id}/analytics` A daily series of sent emails, replies, positive replies, bounces and unsubscribes, with totals and rates for the window. Rates count people, not emails. | Cost | What it does | Key scopes | | --- | --- | --- | | Free | Reads only | argorant:read_counts | Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `campaign_id` | path | string | yes | The campaign id from create or list. | | `days` | query | integer | no | Window in days, up to 365 (default 30). | Example request ```bash curl -X GET "https://app.argorant.com/api/v1/campaigns/7f3a2c1e-9b4d-4e8a-a1c2-5d6e7f8a9b0c/analytics?days=30" \ -H "Authorization: Bearer $ARGORANT_API_KEY" ``` Example answer (200) ```json { "campaign_id": "7f3a2c1e-9b4d-4e8a-a1c2-5d6e7f8a9b0c", "days": 30, "totals": { "sent": 1188, "replies": 41, "positive": 9, "bounces": 3, "unsubscribes": 1, "contacted_leads": 1100, "replied_leads": 38, "reply_rate": 3.45, "positive_rate": 0.82, "bounce_rate": 0.27 }, "series": [ { "day": "2026-09-17", "sent": 120, "replies": 4, "positive": 1, "bounces": 0, "unsubscribes": 0 } ] } ``` It can answer with these errors (status and code): 401 unauthorized; 403 scope_missing; 404 not_found; 422 validation_error; 429 rate_limited. ### Replies to a campaign `GET /api/v1/campaigns/{campaign_id}/replies` Replies to this campaign, newest first, with their status. For replies across all campaigns use the Inbox. | Cost | What it does | Key scopes | | --- | --- | --- | | Free | Reads only | argorant:read_counts | Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `campaign_id` | path | string | yes | The campaign id from create or list. | | `limit` | query | integer | no | Rows per page, 1 to 200 (default 50). | | `cursor` | query | string | no | The next_cursor of the previous page. Leave out for the first page. | | `offset` | query | integer | no | Rows to skip, as an alternative to cursor. | Example request ```bash curl -X GET "https://app.argorant.com/api/v1/campaigns/7f3a2c1e-9b4d-4e8a-a1c2-5d6e7f8a9b0c/replies?limit=50" \ -H "Authorization: Bearer $ARGORANT_API_KEY" ``` Example answer (200) ```json { "replies": [ { "id": "a1b2c3d4-0000-4000-8000-000000000001", "from_email": "jane.doe@example-acme.com", "first_name": "Jane", "last_name": "Doe", "company": "Acme", "subject": "Re: Quick question, Jane", "body": "Happy to talk. Does Thursday 10:00 work?", "classification": "positive", "created_at": "2026-09-18T14:03:11+00:00" } ], "total": 1, "limit": 25, "offset": 0, "next_cursor": null, "has_more": false } ``` It can answer with these errors (status and code): 401 unauthorized; 403 scope_missing; 404 not_found; 422 validation_error; 429 rate_limited. ### Follow-up sequences `GET /api/v1/campaigns/{campaign_id}/subsequences` Sequences that start when a reply contains a keyword, for example "pricing" or "next quarter". | Cost | What it does | Key scopes | | --- | --- | --- | | Free | Reads only | argorant:read_counts | Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `campaign_id` | path | string | yes | The campaign id from create or list. | Example request ```bash curl -X GET "https://app.argorant.com/api/v1/campaigns/7f3a2c1e-9b4d-4e8a-a1c2-5d6e7f8a9b0c/subsequences" \ -H "Authorization: Bearer $ARGORANT_API_KEY" ``` Example answer (200) ```json { "subsequences": [ { "id": "5e4d3c2b-1a09-4f8e-9d7c-6b5a4f3e2d1c", "name": "Asked about pricing", "keywords": [ "pricing", "cost" ], "steps": [ { "subject": "Re: {{thread_subject}}", "body": "Here is how pricing works...", "delay_days": 0 } ] } ] } ``` It can answer with these errors (status and code): 401 unauthorized; 403 scope_missing; 404 not_found; 429 rate_limited. ### Set follow-up sequences (POST) `POST /api/v1/campaigns/{campaign_id}/subsequences` The same as PUT /api/v1/campaigns/{campaign_id}/subsequences, for clients that cannot send PUT. Replaces the campaign's follow-up sequences: up to 5, each with a name, 1 to 10 keywords and 1 to 8 emails. | Cost | What it does | Key scopes | | --- | --- | --- | | Free | writes | argorant:manage_lists | Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `campaign_id` | path | string | yes | The campaign id from create or list. | | `Idempotency-Key` | header | string | no | Any unique text up to 128 characters. A retry with the same key and the same body within 24 hours returns the first answer (with the header Idempotent-Replayed: true) instead of doing the work twice. The same key with another body answers 409 idempotency_conflict. | Body fields (JSON) | Field | Type | Required | Description | | --- | --- | --- | --- | | `subsequences` | array of object | yes | Up to 5 sequences, the same shape as PUT. | Example request ```bash curl -X POST "https://app.argorant.com/api/v1/campaigns/7f3a2c1e-9b4d-4e8a-a1c2-5d6e7f8a9b0c/subsequences" \ -H "Authorization: Bearer $ARGORANT_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{"subsequences":[{"name":"Asked about pricing","keywords":["pricing","cost"],"emails":[{"body":"Here is how pricing works...","delay_days":0}]}]}' ``` Example answer (200) ```json { "subsequences": [ { "id": "5e4d3c2b-1a09-4f8e-9d7c-6b5a4f3e2d1c", "name": "Asked about pricing", "keywords": [ "pricing", "cost" ] } ] } ``` It can answer with these errors (status and code): 401 unauthorized; 403 scope_missing; 404 not_found; 409 idempotency_conflict; 422 validation_error; 429 rate_limited. ### Set follow-up sequences `PUT /api/v1/campaigns/{campaign_id}/subsequences` Replaces the campaign's follow-up sequences: up to 5, each with a name, 1 to 10 keywords and 1 to 8 emails. A reply that contains a keyword moves that person into the first matching sequence. Keywords also count in capitals, as a plural, with a small typo or inside a short sentence. A keyword after "not" ("not interested") and a reply that asks to stop never start one. Email 1 defaults to the subject "Re: {{thread_subject}}". POST does the same. | Cost | What it does | Key scopes | | --- | --- | --- | | Free | writes | argorant:manage_lists | Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `campaign_id` | path | string | yes | The campaign id from create or list. | | `Idempotency-Key` | header | string | no | Any unique text up to 128 characters. A retry with the same key and the same body within 24 hours returns the first answer (with the header Idempotent-Replayed: true) instead of doing the work twice. The same key with another body answers 409 idempotency_conflict. | Body fields (JSON) | Field | Type | Required | Description | | --- | --- | --- | --- | | `subsequences` | array of object | yes | Up to 5 sequences. | Example request ```bash curl -X PUT "https://app.argorant.com/api/v1/campaigns/7f3a2c1e-9b4d-4e8a-a1c2-5d6e7f8a9b0c/subsequences" \ -H "Authorization: Bearer $ARGORANT_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{"subsequences":[{"name":"Asked about pricing","keywords":["pricing","cost"],"emails":[{"body":"Here is how pricing works...","delay_days":0}]}]}' ``` Example answer (200) ```json { "subsequences": [ { "id": "5e4d3c2b-1a09-4f8e-9d7c-6b5a4f3e2d1c", "name": "Asked about pricing", "keywords": [ "pricing", "cost" ] } ] } ``` It can answer with these errors (status and code): 400 invalid_request; 401 unauthorized; 403 scope_missing; 404 not_found; 409 idempotency_conflict; 422 validation_error; 429 rate_limited. ### List conversations `GET /api/v1/inbox` Replies, bounces and unsubscribes across every campaign, newest first. Texts are cut to 400 characters here; open a conversation for the full text. The inbox holds the newest 500 conversations per query; filter by campaign or folder to reach older ones. | Cost | What it does | Key scopes | | --- | --- | --- | | Free | Reads only | argorant:read_counts | Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `folder` | query | string | no | Which conversations. One of all, replies, interested, not_interested, out_of_office, bounces, unsubscribes. | | `campaign_id` | query | string | no | Only this campaign. | | `classification` | query | string | no | Only this status, any key from GET /api/v1/reply-statuses. | | `q` | query | string | no | Search subject, text, sender and company. | | `limit` | query | integer | no | Rows per page, 1 to 500 (default 100). | | `cursor` | query | string | no | The next_cursor of the previous page. Leave out for the first page. | | `offset` | query | integer | no | Rows to skip, as an alternative to cursor. | Example request ```bash curl -X GET "https://app.argorant.com/api/v1/inbox?folder=replies&limit=100" \ -H "Authorization: Bearer $ARGORANT_API_KEY" ``` Example answer (200) ```json { "folder": "replies", "count": 1, "events": [ { "id": "native-conversation:lead:7f3a2c1e-9b4d-4e8a-a1c2-5d6e7f8a9b0c:0c9d8e7f-6a5b-4c3d-8e2f-1a0b9c8d7e6f", "event_type": "provider_reply", "classification": "positive", "campaign_id": "7f3a2c1e-9b4d-4e8a-a1c2-5d6e7f8a9b0c", "campaign_name": "Q4 CFO outreach", "from_email": "jane.doe@example-acme.com", "lead_name": "Jane Doe", "company": "Acme", "inbox_email": "elena@northgate-advisory.com", "subject": "Re: Quick question, Jane", "body": "Happy to talk. Does Thursday 10:00 work?", "created_at": "2026-09-18T14:03:11+00:00", "reply_url": "/api/v1/inbox/native-conversation:lead:7f3a2c1e-9b4d-4e8a-a1c2-5d6e7f8a9b0c:0c9d8e7f-6a5b-4c3d-8e2f-1a0b9c8d7e6f/reply" } ], "total": 1, "limit": 25, "offset": 0, "next_cursor": null, "has_more": false } ``` It can answer with these errors (status and code): 401 unauthorized; 403 scope_missing; 422 validation_error; 429 rate_limited. ### Open a conversation `GET /api/v1/inbox/{event_id}` One conversation with the full text and the whole thread, oldest first: your emails, their replies, your answers and forwards. | Cost | What it does | Key scopes | | --- | --- | --- | | Free | Reads only | argorant:read_counts | Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `event_id` | path | string | yes | The conversation id from GET /api/v1/inbox. | Example request ```bash curl -X GET "https://app.argorant.com/api/v1/inbox/native-conversation%3Alead%3A7f3a2c1e-9b4d-4e8a-a1c2-5d6e7f8a9b0c%3A0c9d8e7f-6a5b-4c3d-8e2f-1a0b9c8d7e6f" \ -H "Authorization: Bearer $ARGORANT_API_KEY" ``` Example answer (200) ```json { "event": { "id": "native-conversation:lead:7f3a2c1e-9b4d-4e8a-a1c2-5d6e7f8a9b0c:0c9d8e7f-6a5b-4c3d-8e2f-1a0b9c8d7e6f", "campaign_name": "Q4 CFO outreach", "from_email": "jane.doe@example-acme.com", "inbox_email": "elena@northgate-advisory.com", "subject": "Re: Quick question, Jane", "body": "Happy to talk. Does Thursday 10:00 work?\n\nJane", "classification": "positive", "created_at": "2026-09-18T14:03:11+00:00", "thread": [ { "direction": "outbound", "type": "send", "step_number": 1, "subject": "Quick question, Jane", "created_at": "2026-09-17T09:12:00+00:00" }, { "direction": "inbound", "type": "reply", "subject": "Re: Quick question, Jane", "created_at": "2026-09-18T14:03:11+00:00" } ] } } ``` It can answer with these errors (status and code): 401 unauthorized; 403 scope_missing; 404 not_found; 429 rate_limited. ### Answer in the thread `POST /api/v1/inbox/{event_id}/reply` Sends a plain text answer in the same thread from the mailbox that received the reply. It goes out at once, so send only what the user approved. | Cost | What it does | Key scopes | | --- | --- | --- | | Free | sends email | argorant:manage_lists | Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `event_id` | path | string | yes | The conversation id from GET /api/v1/inbox. | | `Idempotency-Key` | header | string | no | Any unique text up to 128 characters. A retry with the same key and the same body within 24 hours returns the first answer (with the header Idempotent-Replayed: true) instead of doing the work twice. The same key with another body answers 409 idempotency_conflict. | Body fields (JSON) | Field | Type | Required | Description | | --- | --- | --- | --- | | `body` | string | yes | The answer, plain text. | Example request ```bash curl -X POST "https://app.argorant.com/api/v1/inbox/native-conversation%3Alead%3A7f3a2c1e-9b4d-4e8a-a1c2-5d6e7f8a9b0c%3A0c9d8e7f-6a5b-4c3d-8e2f-1a0b9c8d7e6f/reply" \ -H "Authorization: Bearer $ARGORANT_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{"body":"Thursday 10:00 works. I will send an invite."}' ``` Example answer (200) ```json { "ok": true, "sent": { "ok": true } } ``` It can answer with these errors (status and code): 400 invalid_request; 401 unauthorized; 403 scope_missing; 404 not_found; 409 idempotency_conflict; 422 validation_error; 429 rate_limited. ### Forward a conversation `POST /api/v1/inbox/{event_id}/forward` Forwards the conversation with its history and attachments to up to 10 addresses, from the mailbox that received it. It goes out at once with `delivery: checking`; within three minutes the conversation shows `delivered` or `rejected` with the reason. | Cost | What it does | Key scopes | | --- | --- | --- | | Free | sends email | argorant:manage_lists | Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `event_id` | path | string | yes | The conversation id from GET /api/v1/inbox. | | `Idempotency-Key` | header | string | no | Any unique text up to 128 characters. A retry with the same key and the same body within 24 hours returns the first answer (with the header Idempotent-Replayed: true) instead of doing the work twice. The same key with another body answers 409 idempotency_conflict. | Body fields (JSON) | Field | Type | Required | Description | | --- | --- | --- | --- | | `to` | array of string | yes | 1 to 10 addresses. | | `note` | string | no | A note above the forwarded text, up to 4,000 characters. | Example request ```bash curl -X POST "https://app.argorant.com/api/v1/inbox/native-conversation%3Alead%3A7f3a2c1e-9b4d-4e8a-a1c2-5d6e7f8a9b0c%3A0c9d8e7f-6a5b-4c3d-8e2f-1a0b9c8d7e6f/forward" \ -H "Authorization: Bearer $ARGORANT_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{"to":["sales-lead@northgate-advisory.com"],"note":"Hot lead, please call her this week."}' ``` Example answer (200) ```json { "ok": true, "forwarded_to": [ "sales-lead@northgate-advisory.com" ], "from": "elena@northgate-advisory.com", "forward_id": "f1e2d3c4-b5a6-4978-8a9b-0c1d2e3f4a5b", "delivery": "checking" } ``` It can answer with these errors (status and code): 401 unauthorized; 403 scope_missing; 404 not_found; 409 idempotency_conflict; 422 validation_error; 429 rate_limited. ### Set the status `POST /api/v1/inbox/{event_id}/classify` Stores a status on the conversation: any key from GET /api/v1/reply-statuses, built in or one of your own stages. The built-in interested status has the key `positive`; `interested` is accepted as the same thing. | Cost | What it does | Key scopes | | --- | --- | --- | | Free | writes | argorant:manage_lists | Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `event_id` | path | string | yes | The conversation id from GET /api/v1/inbox. | | `Idempotency-Key` | header | string | no | Any unique text up to 128 characters. A retry with the same key and the same body within 24 hours returns the first answer (with the header Idempotent-Replayed: true) instead of doing the work twice. The same key with another body answers 409 idempotency_conflict. | Body fields (JSON) | Field | Type | Required | Description | | --- | --- | --- | --- | | `classification` | string | yes | A status key, for example positive, meeting_booked or proposal_sent. | Example request ```bash curl -X POST "https://app.argorant.com/api/v1/inbox/native-conversation%3Alead%3A7f3a2c1e-9b4d-4e8a-a1c2-5d6e7f8a9b0c%3A0c9d8e7f-6a5b-4c3d-8e2f-1a0b9c8d7e6f/classify" \ -H "Authorization: Bearer $ARGORANT_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{"classification":"meeting_booked"}' ``` Example answer (200) ```json { "ok": true, "id": "native-conversation:lead:7f3a2c1e-9b4d-4e8a-a1c2-5d6e7f8a9b0c:0c9d8e7f-6a5b-4c3d-8e2f-1a0b9c8d7e6f", "classification": "meeting_booked" } ``` It can answer with these errors (status and code): 401 unauthorized; 403 scope_missing; 404 not_found; 409 idempotency_conflict; 422 validation_error; 429 rate_limited. ### Reply statuses `GET /api/v1/reply-statuses` The labels you can set on a conversation: the standard ones (positive, meeting_request, out_of_office, unsubscribe, neutral), the extra ones your workspace switched on (not_interested, question, referral, wrong_person, meeting_booked) and the labels your workspace added. Each label says whether it is visible. | Cost | What it does | Key scopes | | --- | --- | --- | | Free | Reads only | argorant:read_counts | Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `limit` | query | integer | no | Rows per page, 1 to 500 (default 500). | | `cursor` | query | string | no | The next_cursor of the previous page. Leave out for the first page. | | `offset` | query | integer | no | Rows to skip, as an alternative to cursor. | Example request ```bash curl -X GET "https://app.argorant.com/api/v1/reply-statuses?limit=500" \ -H "Authorization: Bearer $ARGORANT_API_KEY" ``` Example answer (200) ```json { "statuses": [ { "key": "positive", "label": "Interested", "color": "lime", "description": "Wants to talk, learn more, get pricing or try it.", "builtin": true, "standard": true, "visible": true }, { "key": "proposal_sent", "label": "Proposal sent", "color": "purple", "description": "", "builtin": false, "standard": false, "visible": true } ], "total": 2, "limit": 25, "offset": 0, "next_cursor": null, "has_more": false } ``` It can answer with these errors (status and code): 401 unauthorized; 403 scope_missing; 422 validation_error; 429 rate_limited. ### Add a pipeline stage `POST /api/v1/reply-statuses` Adds a stage of your own, such as Proposal sent or Demo scheduled. The key is made from the label. | Cost | What it does | Key scopes | | --- | --- | --- | | Free | writes | argorant:manage_lists | Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `Idempotency-Key` | header | string | no | Any unique text up to 128 characters. A retry with the same key and the same body within 24 hours returns the first answer (with the header Idempotent-Replayed: true) instead of doing the work twice. The same key with another body answers 409 idempotency_conflict. | Body fields (JSON) | Field | Type | Required | Description | | --- | --- | --- | --- | | `label` | string | yes | Up to 40 characters. | | `color` | string | no | Color (default blue). One of lime, blue, rose, neutral, purple, yellow. | | `description` | string | no | What the stage means, up to 300 characters. | Example request ```bash curl -X POST "https://app.argorant.com/api/v1/reply-statuses" \ -H "Authorization: Bearer $ARGORANT_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{"label":"Proposal sent","color":"purple"}' ``` Example answer (200) ```json { "status": { "key": "proposal_sent", "label": "Proposal sent", "color": "purple", "builtin": false, "visible": true, "description": "" } } ``` It can answer with these errors (status and code): 401 unauthorized; 403 scope_missing; 409 conflict, idempotency_conflict; 422 validation_error; 429 rate_limited. ### Change a stage `PATCH /api/v1/reply-statuses/{key}` Rename, describe, recolor, hide or show a stage. Built-in statuses can only be hidden or shown; neutral always stays visible. | Cost | What it does | Key scopes | | --- | --- | --- | | Free | writes | argorant:manage_lists | Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `key` | path | string | yes | The status key. | | `Idempotency-Key` | header | string | no | Any unique text up to 128 characters. A retry with the same key and the same body within 24 hours returns the first answer (with the header Idempotent-Replayed: true) instead of doing the work twice. The same key with another body answers 409 idempotency_conflict. | Body fields (JSON) | Field | Type | Required | Description | | --- | --- | --- | --- | | `label` | string | no | New name. | | `color` | string | no | New color. One of lime, blue, rose, neutral, purple, yellow. | | `description` | string | no | New description. | | `visible` | boolean | no | Show or hide in the app. | Example request ```bash curl -X PATCH "https://app.argorant.com/api/v1/reply-statuses/proposal_sent" \ -H "Authorization: Bearer $ARGORANT_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{"label":"Proposal out","visible":true}' ``` Example answer (200) ```json { "status": { "key": "proposal_sent", "label": "Proposal out", "color": "purple", "builtin": false, "visible": true } } ``` It can answer with these errors (status and code): 401 unauthorized; 403 scope_missing; 404 not_found; 409 conflict, idempotency_conflict; 422 validation_error; 429 rate_limited. ### Delete a stage `DELETE /api/v1/reply-statuses/{key}` Deletes a stage your workspace added. Conversations that carried it go back to neutral. Built-in statuses cannot be deleted; hide them instead. | Cost | What it does | Key scopes | | --- | --- | --- | | Free | writes | argorant:manage_lists | Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `key` | path | string | yes | The status key. | | `Idempotency-Key` | header | string | no | Any unique text up to 128 characters. A retry with the same key and the same body within 24 hours returns the first answer (with the header Idempotent-Replayed: true) instead of doing the work twice. The same key with another body answers 409 idempotency_conflict. | Example request ```bash curl -X DELETE "https://app.argorant.com/api/v1/reply-statuses/proposal_sent" \ -H "Authorization: Bearer $ARGORANT_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" ``` Example answer (200) ```json { "ok": true, "removed": "proposal_sent" } ``` It can answer with these errors (status and code): 401 unauthorized; 403 scope_missing; 404 not_found; 409 idempotency_conflict; 429 rate_limited. ### List blocked addresses and domains `GET /api/v1/blocklist` Addresses and domains your campaigns never contact, newest first, 50 per page by default and at most 1,000. Follow `next_cursor` for the next page; `total` and `counts` cover the whole list. `q` finds entries that contain a text. A block covers every campaign of the workspace (`scope: workspace`) or only one campaign (`scope: campaign` with its `campaign_id`). `campaign_id` lists what applies to that campaign: its own blocks plus the workspace ones, or only its own with `scope=campaign`. `fields=compact` returns only value, type, scope, campaign_id and created_at. | Cost | What it does | Key scopes | | --- | --- | --- | | Free | Reads only | argorant:read_counts | Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `limit` | query | integer | no | Entries per page, 1 to 1,000 (default 50). A larger value returns 1,000. | | `cursor` | query | string | no | The next_cursor of the previous page. Leave out for the first page. | | `offset` | query | integer | no | Rows to skip, as an alternative to cursor. | | `q` | query | string | no | Only entries whose value or reason contains this text (up to 200 characters). | | `type` | query | string | no | Only addresses or only domains. One of email, domain. | | `scope` | query | string | no | all (default), workspace or campaign. One of all, workspace, campaign. | | `campaign_id` | query | string | no | What applies to this campaign. | | `fields` | query | string | no | full (default) or compact. One of full, compact. | Example request ```bash curl -X GET "https://app.argorant.com/api/v1/blocklist?limit=50&q=acme" \ -H "Authorization: Bearer $ARGORANT_API_KEY" ``` Example answer (200) ```json { "entries": [ { "id": "c9a94730-604c-4156-bee1-d52e24a3f847", "value": "competitor.com", "type": "domain", "scope": "workspace", "created_at": "2026-09-19T12:54:32+00:00", "reason": "customer", "yours": true }, { "id": "0b6f3f2e-1d4c-4a5b-9c8d-7e6f5a4b3c2d", "value": "jane@acme.com", "type": "email", "scope": "campaign", "campaign_id": "7f3a2c1e-9b4d-4e8a-a1c2-5d6e7f8a9b0c", "created_at": "2026-10-21T09:12:00+00:00", "reason": "manual", "yours": true, "campaign_name": "Q4 CFO outreach" } ], "total": 383, "limit": 50, "offset": 0, "next_cursor": "bzo1MA", "has_more": true, "counts": { "workspace": 380, "campaign": 3, "email": 300, "domain": 83 } } ``` It can answer with these errors (status and code): 401 unauthorized; 403 scope_missing; 404 not_found; 422 validation_error; 429 rate_limited. ### Block an address or a domain `POST /api/v1/blocklist` Send one email address or domain. Matching people already in your campaigns stop getting emails at once, and future enrollments skip them. With `campaign_ids` the block covers only those campaigns (up to 50). For many values use POST /api/v1/blocklist/bulk. | Cost | What it does | Key scopes | | --- | --- | --- | | Free | writes | argorant:manage_lists | Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `Idempotency-Key` | header | string | no | Any unique text up to 128 characters. A retry with the same key and the same body within 24 hours returns the first answer (with the header Idempotent-Replayed: true) instead of doing the work twice. The same key with another body answers 409 idempotency_conflict. | Body fields (JSON) | Field | Type | Required | Description | | --- | --- | --- | --- | | `value` | string | yes | An email address or a domain. | | `reason` | string | no | Why, for your own records (default manual, up to 200 characters). | | `campaign_ids` | array of string | no | Block only in these campaigns, up to 50. Leave out to block in every campaign. | Example request ```bash curl -X POST "https://app.argorant.com/api/v1/blocklist" \ -H "Authorization: Bearer $ARGORANT_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{"value":"competitor.com","reason":"customer"}' ``` Example answer (200) ```json { "ok": true, "id": "c9a94730-604c-4156-bee1-d52e24a3f847", "type": "domain", "value": "competitor.com", "scope": "workspace", "leads_suppressed": 3 } ``` It can answer with these errors (status and code): 400 invalid_request; 401 unauthorized; 403 scope_missing; 404 not_found; 409 idempotency_conflict; 422 validation_error; 429 rate_limited. ### Block many addresses or domains `POST /api/v1/blocklist/bulk` Up to 5,000 email addresses or domains per call, as `values` or as `csv` text (the first address or domain of each row counts; a header row is fine). Send more in several calls. Without `campaign_ids` the blocks cover every campaign of the workspace; with `campaign_ids` (up to 50, and values times campaigns at most 50,000) only those campaigns. Send `dry_run: true` first to see how many entries would be added and how many people waiting in campaigns would be stopped; nothing changes. Up to 500 new entries are done in the call. More are saved and applied in the background: the answer is 202 with a `job_id` to follow at GET /api/v1/blocklist/jobs/{job_id}. Entries are saved before people are stopped, so a block always holds. | Cost | What it does | Key scopes | | --- | --- | --- | | Free | writes | argorant:manage_lists | Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `Idempotency-Key` | header | string | no | Any unique text up to 128 characters. A retry with the same key and the same body within 24 hours returns the first answer (with the header Idempotent-Replayed: true) instead of doing the work twice. The same key with another body answers 409 idempotency_conflict. | Body fields (JSON) | Field | Type | Required | Description | | --- | --- | --- | --- | | `values` | array of string | no | Up to 5,000 email addresses or domains. | | `csv` | string | no | CSV text instead of values, up to 5,000 rows and 2,000,000 characters. | | `campaign_ids` | array of string | no | Block only in these campaigns, up to 50. | | `reason` | string | no | Why, for your own records (default manual). | | `dry_run` | boolean | no | true only counts and changes nothing. | Example request ```bash curl -X POST "https://app.argorant.com/api/v1/blocklist/bulk" \ -H "Authorization: Bearer $ARGORANT_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{"values":["competitor.com","jane@acme.com"],"dry_run":true}' ``` Example answer (200) ```json { "ok": true, "dry_run": true, "found": 2, "invalid": 0, "invalid_examples": [], "duplicates": 0, "scope": "workspace", "would_add": 2, "already_listed": 0, "leads_to_stop": 37, "complete": true, "status": "done", "job_id": "5e4d3c2b-1a09-4f8e-8d7c-6b5a49382716", "summary": "2 new entries would be added (0 already listed). 37 campaign leads would be stopped." } ``` It can answer with these errors (status and code): 400 invalid_request; 401 unauthorized; 403 scope_missing; 404 not_found; 409 idempotency_conflict; 413 invalid_request; 422 validation_error; 429 rate_limited. ### Unblock many addresses or domains `POST /api/v1/blocklist/bulk-remove` Removes up to 5,000 entries per call, by `values` (or `csv`) or by entry `ids`. Without `campaign_ids` it removes workspace entries (and campaign entries named by id); with `campaign_ids` only those campaigns' entries. `dry_run: true` only counts. People who were stopped by an entry are not added back on their own. | Cost | What it does | Key scopes | | --- | --- | --- | | Free | writes | argorant:manage_lists | Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `Idempotency-Key` | header | string | no | Any unique text up to 128 characters. A retry with the same key and the same body within 24 hours returns the first answer (with the header Idempotent-Replayed: true) instead of doing the work twice. The same key with another body answers 409 idempotency_conflict. | Body fields (JSON) | Field | Type | Required | Description | | --- | --- | --- | --- | | `values` | array of string | no | Up to 5,000 email addresses or domains. | | `csv` | string | no | CSV text instead of values, up to 5,000 rows. | | `ids` | array of string | no | Up to 5,000 entry ids from the list. | | `campaign_ids` | array of string | no | Remove only these campaigns' entries, up to 50. | | `dry_run` | boolean | no | true only counts and changes nothing. | Example request ```bash curl -X POST "https://app.argorant.com/api/v1/blocklist/bulk-remove" \ -H "Authorization: Bearer $ARGORANT_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{"values":["competitor.com"],"dry_run":false}' ``` Example answer (200) ```json { "ok": true, "dry_run": false, "found": 1, "invalid": 0, "invalid_examples": [], "removed": 1, "not_listed": 0, "scope": "workspace", "summary": "Removed 1 entries. People stopped earlier are not added back on their own." } ``` It can answer with these errors (status and code): 401 unauthorized; 403 scope_missing; 404 not_found; 409 idempotency_conflict; 413 invalid_request; 422 validation_error; 429 rate_limited. ### Follow a large block `GET /api/v1/blocklist/jobs/{job_id}` Progress of a bulk block or of a dry run that needed more time. `status` is queued, running, done or failed; `leads_suppressed` (or `leads_to_stop` for a dry run) grows as it works. | Cost | What it does | Key scopes | | --- | --- | --- | | Free | Reads only | argorant:read_counts | Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `job_id` | path | string | yes | The job_id from POST /api/v1/blocklist/bulk. | Example request ```bash curl -X GET "https://app.argorant.com/api/v1/blocklist/jobs/5e4d3c2b-1a09-4f8e-8d7c-6b5a49382716" \ -H "Authorization: Bearer $ARGORANT_API_KEY" ``` Example answer (200) ```json { "job_id": "5e4d3c2b-1a09-4f8e-8d7c-6b5a49382716", "kind": "add", "status": "done", "values": 4200, "scope": "workspace", "added": 4160, "already_listed": 40, "leads_suppressed": 912, "progress_percent": 100, "created_at": "2026-10-21T15:20:00+00:00", "finished_at": "2026-10-21T15:21:10+00:00", "summary": "Added 4,160; 40 were already listed. Stopped 912 campaign leads." } ``` It can answer with these errors (status and code): 401 unauthorized; 403 scope_missing; 404 not_found; 429 rate_limited. ### Unblock `DELETE /api/v1/blocklist/{entry_id}` Removes one entry your workspace added, a workspace or a campaign block. Campaigns may contact that address or domain again. | Cost | What it does | Key scopes | | --- | --- | --- | | Free | writes | argorant:manage_lists | Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `entry_id` | path | string | yes | The entry id from the list. | | `Idempotency-Key` | header | string | no | Any unique text up to 128 characters. A retry with the same key and the same body within 24 hours returns the first answer (with the header Idempotent-Replayed: true) instead of doing the work twice. The same key with another body answers 409 idempotency_conflict. | Example request ```bash curl -X DELETE "https://app.argorant.com/api/v1/blocklist/c9a94730-604c-4156-bee1-d52e24a3f847" \ -H "Authorization: Bearer $ARGORANT_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" ``` Example answer (200) ```json { "ok": true, "removed": "c9a94730-604c-4156-bee1-d52e24a3f847", "scope": "workspace" } ``` It can answer with these errors (status and code): 401 unauthorized; 403 scope_missing; 404 not_found; 409 idempotency_conflict; 429 rate_limited. ### List mailboxes `GET /api/v1/inboxes` The mailboxes connected to your workspace (Google, Microsoft and any other provider), a page at a time and ordered by address, with status, today's sends against the daily limit, tags, warm-up and what needs fixing. Narrow it by domain, status, tag, provider or text. The first page also has `summary`: how many mailboxes are in each status, on each domain and with each tag. No passwords or tokens are ever returned. | Cost | What it does | Key scopes | | --- | --- | --- | | Free | Reads only | argorant:read_counts | Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `limit` | query | integer | no | Rows per page, 1 to 500 (default 50). | | `cursor` | query | string | no | The next_cursor of the previous page. Leave out for the first page. | | `domain` | query | string | no | One domain, or several separated by commas. | | `status` | query | string | no | sendable, warming, not_connected, needs_attention or paused; several separated by commas. | | `tag` | query | string | no | Mailboxes that carry this tag; several separated by commas means all of them. Capitals do not matter. | | `provider` | query | string | no | google, ms365 or smtp. One of google, ms365, smtp. | | `q` | query | string | no | Text in the address or the name. | | `summary` | query | boolean | no | Set false to leave the summary out of the first page. | | `summary_domains` | query | integer | no | How many domains the summary lists, 0 to 500 (default 25). | Example request ```bash curl -X GET "https://app.argorant.com/api/v1/inboxes?limit=50&domain=northgate-advisory.com&status=needs_attention" \ -H "Authorization: Bearer $ARGORANT_API_KEY" ``` Example answer (200) ```json { "inboxes": [ { "email": "elena@northgate-advisory.com", "name": "Elena Vaughn", "provider": "google", "domain": "northgate-advisory.com", "status": "sendable", "status_label": "Sending", "daily_limit": 40, "sent_today": 38, "tags": [ "outbound" ], "needs_attention": false, "warmup": { "on": true, "per_day": 10 } } ], "total": 1, "limit": 50, "next_cursor": null, "has_more": false, "filters": { "domain": [ "northgate-advisory.com" ] }, "summary": { "total": 1, "by_status": { "sendable": 1 }, "domains_total": 1, "by_domain": [ { "domain": "northgate-advisory.com", "total": 1, "by_status": { "sendable": 1 } } ], "by_tag": [ { "tag": "outbound", "total": 1 } ] } } ``` It can answer with these errors (status and code): 401 unauthorized; 403 scope_missing; 422 validation_error; 429 rate_limited. ### Change a mailbox `PATCH /api/v1/inboxes/{email}` Daily cold email limit, warm-up on or off, whether it may send, display name and time zone. Only the fields you send change. | Cost | What it does | Key scopes | | --- | --- | --- | | Free | writes | argorant:manage_lists | Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `email` | path | string | yes | The mailbox address. | | `Idempotency-Key` | header | string | no | Any unique text up to 128 characters. A retry with the same key and the same body within 24 hours returns the first answer (with the header Idempotent-Replayed: true) instead of doing the work twice. The same key with another body answers 409 idempotency_conflict. | Body fields (JSON) | Field | Type | Required | Description | | --- | --- | --- | --- | | `daily_limit` | integer | no | Cold emails a day. | | `warmup` | boolean | no | Warm-up on or off. | | `warmup_per_day` | integer | no | Warm-up emails a day, 0 (off) to 10. A number wins over warmup. | | `active` | boolean | no | May send. | | `display_name` | string | no | Name shown to recipients. | | `timezone` | string | no | Time zone name. | Example request ```bash curl -X PATCH "https://app.argorant.com/api/v1/inboxes/elena%40northgate-advisory.com" \ -H "Authorization: Bearer $ARGORANT_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{"daily_limit":40,"warmup":true}' ``` Example answer (200) ```json { "inbox": { "email": "elena@northgate-advisory.com", "name": "Elena Vaughn", "provider": "google", "status": "connected", "health": "healthy", "daily_limit": 40, "active": true, "warmup": true, "timezone": "Europe/London" }, "changed": [ "daily_limit", "warmup" ] } ``` It can answer with these errors (status and code): 401 unauthorized; 403 scope_missing; 404 not_found; 409 idempotency_conflict; 422 validation_error; 429 rate_limited. ### Disconnect a mailbox `DELETE /api/v1/inboxes/{email}` Takes the mailbox off its campaigns and disconnects it. Nothing more sends from it. It does not delete the mailbox at Google or Microsoft. | Cost | What it does | Key scopes | | --- | --- | --- | | Free | writes | argorant:manage_lists | Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `email` | path | string | yes | The mailbox address. | | `Idempotency-Key` | header | string | no | Any unique text up to 128 characters. A retry with the same key and the same body within 24 hours returns the first answer (with the header Idempotent-Replayed: true) instead of doing the work twice. The same key with another body answers 409 idempotency_conflict. | Example request ```bash curl -X DELETE "https://app.argorant.com/api/v1/inboxes/elena%40northgate-advisory.com" \ -H "Authorization: Bearer $ARGORANT_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" ``` Example answer (200) ```json { "ok": true, "disconnected": "elena@northgate-advisory.com" } ``` It can answer with these errors (status and code): 401 unauthorized; 403 scope_missing; 404 not_found; 409 idempotency_conflict; 429 rate_limited. ### Change many mailboxes `POST /api/v1/inboxes/update` The same change for many mailboxes in one call: daily limit, warm-up (on or off, or a number a day), switched on or off, or time zone. Choose them by address, domain, tag or status, or `all_connected`; for every mailbox send `status: ["any"]`. The default is a preview that counts what would change and changes nothing. Send `preview: false` to apply. Switching off more than one mailbox also needs `confirmed: true`, because people queued on them wait for another mailbox. | Cost | What it does | Key scopes | | --- | --- | --- | | Free | writes | argorant:manage_lists | Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `Idempotency-Key` | header | string | no | Any unique text up to 128 characters. A retry with the same key and the same body within 24 hours returns the first answer (with the header Idempotent-Replayed: true) instead of doing the work twice. The same key with another body answers 409 idempotency_conflict. | Body fields (JSON) | Field | Type | Required | Description | | --- | --- | --- | --- | | `settings` | object | yes | Only what should change, from daily_limit (1 to 10,000), warmup (true or false), warmup_per_day (0 to 10), active (true or false), timezone (a name such as Europe/Berlin). | | `emails` | array of string | no | Mailbox addresses, when only a few. | | `domains` | array of string | no | Every mailbox on these domains. | | `tags` | array of string | no | Mailboxes that carry all of these tags. | | `status` | array of string | no | sendable, warming, not_connected, needs_attention, paused, or any. | | `all_connected` | boolean | no | Every signed-in mailbox. | | `preview` | boolean | no | true (default) only counts. false applies the change. | | `confirmed` | boolean | no | Needed to switch off more than one mailbox. | Example request ```bash curl -X POST "https://app.argorant.com/api/v1/inboxes/update" \ -H "Authorization: Bearer $ARGORANT_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{"domains":["northgate-advisory.com"],"settings":{"daily_limit":30},"preview":true}' ``` Example answer (200) ```json { "matched": 12, "would_change": 10, "already_set": 2, "preview": true, "summary_text": "10 of 12 mailbox(es) would change, 2 already have these settings. Nothing changed yet." } ``` It can answer with these errors (status and code): 400 invalid_request; 401 unauthorized; 403 scope_missing; 409 conflict, idempotency_conflict; 422 validation_error; 429 rate_limited. ### Connect a Google Workspace `POST /api/v1/inboxes/google-workspace` Two calls. Without `emails` you get what the Workspace admin must add in Google Admin (a client id and its access list) and, once that is done, every mailbox and alias in the Workspace. With `emails` those addresses are connected as senders. No passwords and no sign-in per mailbox. | Cost | What it does | Key scopes | | --- | --- | --- | | Free | writes | argorant:manage_lists | Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `Idempotency-Key` | header | string | no | Any unique text up to 128 characters. A retry with the same key and the same body within 24 hours returns the first answer (with the header Idempotent-Replayed: true) instead of doing the work twice. The same key with another body answers 409 idempotency_conflict. | Body fields (JSON) | Field | Type | Required | Description | | --- | --- | --- | --- | | `admin_email` | string | yes | A Workspace admin address. | | `emails` | array of string | no | Mailboxes to connect. Leave out to only list them. | Example request ```bash curl -X POST "https://app.argorant.com/api/v1/inboxes/google-workspace" \ -H "Authorization: Bearer $ARGORANT_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{"admin_email":"admin@northgate-advisory.com","emails":["elena@northgate-advisory.com"]}' ``` Example answer (200) ```json { "setup": { "client_id": "104912345678901234567", "scopes_csv": "https://www.googleapis.com/auth/gmail.send,https://www.googleapis.com/auth/gmail.readonly" }, "domains": [ "northgate-advisory.com" ], "mailboxes": [ { "email": "elena@northgate-advisory.com", "name": "Elena Vaughn", "connected": false, "alias": false } ] } ``` It can answer with these errors (status and code): 401 unauthorized; 403 scope_missing; 409 idempotency_conflict; 422 validation_error; 429 rate_limited. ### Email provider settings `GET /api/v1/inboxes/smtp/presets` The server names, ports and security of common email providers (Zoho, Fastmail, Yahoo, iCloud, IONOS, Titan, GoDaddy, Namecheap and others). Send a key as `preset` when you test or connect a mailbox and leave the server fields empty. `hint` says what to do at the provider first, for example making an app password. | Cost | What it does | Key scopes | | --- | --- | --- | | Free | Reads only | argorant:manage_lists | Example request ```bash curl -X GET "https://app.argorant.com/api/v1/inboxes/smtp/presets" \ -H "Authorization: Bearer $ARGORANT_API_KEY" ``` Example answer (200) ```json { "presets": [ { "key": "zoho", "label": "Zoho Mail (business domain)", "smtp_host": "smtppro.zoho.com", "smtp_port": 587, "smtp_secure": "starttls", "imap_host": "imappro.zoho.com", "imap_port": 993, "imap_secure": "ssl", "hint": "Turn on IMAP access in your Zoho Mail settings first. With two-step sign-in on, use an app password." }, { "key": "other", "label": "Other provider", "smtp_host": "", "smtp_port": 587, "smtp_secure": "starttls", "imap_host": "", "imap_port": 993, "imap_secure": "ssl", "hint": "Your provider's help pages list these settings, often under IMAP or email app setup." } ] } ``` It can answer with these errors (status and code): 401 unauthorized; 403 scope_missing; 429 rate_limited. ### Test a mailbox sign-in `POST /api/v1/inboxes/smtp/test` Signs in to a mailbox from any email provider twice, once to send (SMTP) and once to read replies (IMAP), and says for each whether it works or what is wrong. Nothing is saved and no email is sent. Google and Microsoft mailboxes connect with their own sign-in instead. Up to 30 tests an hour. | Cost | What it does | Key scopes | | --- | --- | --- | | Free | Reads only | argorant:manage_lists | Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `Idempotency-Key` | header | string | no | Any unique text up to 128 characters. A retry with the same key and the same body within 24 hours returns the first answer (with the header Idempotent-Replayed: true) instead of doing the work twice. The same key with another body answers 409 idempotency_conflict. | Body fields (JSON) | Field | Type | Required | Description | | --- | --- | --- | --- | | `email` | string | yes | The mailbox address that sends. | | `preset` | string | no | An email provider from the presets. Fills every empty server name, port and security setting. One of zoho, zoho_eu, zoho_personal, fastmail, godaddy, titan, hostinger, ionos, ionos_de, ionos_uk, namecheap, yahoo, icloud, outlook, other. | | `smtp_host` | string | no | Server for sending. Needed without a preset. | | `smtp_port` | integer | no | Port for sending. Use 587. If you send 465, Argorant tries 587 with starttls and saves 587 when it works. Needed without a preset. | | `smtp_secure` | string | no | Security for sending, starttls on port 587. Leave out to pick it from the port. One of ssl, starttls, none. | | `smtp_username` | string | no | Sign-in name for sending. Leave out when it is the email address. | | `smtp_password` | string | yes | The password, or an app password when the provider asks for one. Stored encrypted, never returned. | | `imap_host` | string | no | Server for reading replies. Needed without a preset. | | `imap_port` | integer | no | Port for reading replies. | | `imap_secure` | string | no | Security for reading replies. Leave out to use ssl on port 993 and starttls on port 143. One of ssl, starttls, none. | | `imap_username` | string | no | Sign-in name for reading replies. Leave out to use the one for sending. | | `imap_password` | string | no | Password for reading replies. Leave out to use the one for sending. | Example request ```bash curl -X POST "https://app.argorant.com/api/v1/inboxes/smtp/test" \ -H "Authorization: Bearer $ARGORANT_API_KEY" \ -H "Content-Type: application/json" \ -d '{"email":"elena@northgate-advisory.com","preset":"zoho","smtp_password":"app-password"}' ``` Example answer (200) ```json { "works": true, "message": "Sign-in worked for sending and for reading replies.", "smtp": { "works": true, "result": "signed_in", "message": "Sending works." }, "imap": { "works": true, "result": "signed_in", "message": "Reading replies works." } } ``` It can answer with these errors (status and code): 401 unauthorized; 403 scope_missing; 409 idempotency_conflict; 422 validation_error; 429 rate_limited. ### Connect a mailbox from any provider `POST /api/v1/inboxes/smtp` Connects one mailbox from any email provider with its server settings. Argorant first signs in to send and to read replies and connects the mailbox only when both work; otherwise the answer is `sign_in_failed` with the test result. The password is stored encrypted and never returned. Connecting the same address again replaces its settings, which is how a mailbox is reconnected after a password change. A free trial connects up to 2 mailboxes. Up to 30 connects an hour; use the bulk route for more. | Cost | What it does | Key scopes | | --- | --- | --- | | Free | writes | argorant:manage_lists | Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `Idempotency-Key` | header | string | no | Any unique text up to 128 characters. A retry with the same key and the same body within 24 hours returns the first answer (with the header Idempotent-Replayed: true) instead of doing the work twice. The same key with another body answers 409 idempotency_conflict. | Body fields (JSON) | Field | Type | Required | Description | | --- | --- | --- | --- | | `email` | string | yes | The mailbox address that sends. | | `display_name` | string | no | The sender name people see. | | `preset` | string | no | An email provider from the presets. Fills every empty server name, port and security setting. One of zoho, zoho_eu, zoho_personal, fastmail, godaddy, titan, hostinger, ionos, ionos_de, ionos_uk, namecheap, yahoo, icloud, outlook, other. | | `smtp_host` | string | no | Server for sending. Needed without a preset. | | `smtp_port` | integer | no | Port for sending. Use 587. If you send 465, Argorant tries 587 with starttls and saves 587 when it works. Needed without a preset. | | `smtp_secure` | string | no | Security for sending, starttls on port 587. Leave out to pick it from the port. One of ssl, starttls, none. | | `smtp_username` | string | no | Sign-in name for sending. Leave out when it is the email address. | | `smtp_password` | string | yes | The password, or an app password when the provider asks for one. Stored encrypted, never returned. | | `imap_host` | string | no | Server for reading replies. Needed without a preset. | | `imap_port` | integer | no | Port for reading replies. | | `imap_secure` | string | no | Security for reading replies. Leave out to use ssl on port 993 and starttls on port 143. One of ssl, starttls, none. | | `imap_username` | string | no | Sign-in name for reading replies. Leave out to use the one for sending. | | `imap_password` | string | no | Password for reading replies. Leave out to use the one for sending. | | `daily_limit` | integer | no | Cold emails a day from this mailbox. | Example request ```bash curl -X POST "https://app.argorant.com/api/v1/inboxes/smtp" \ -H "Authorization: Bearer $ARGORANT_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{"email":"elena@northgate-advisory.com","display_name":"Elena Vaughn","preset":"zoho","smtp_password":"app-password","daily_limit":30}' ``` Example answer (200) ```json { "inbox": { "email": "elena@northgate-advisory.com", "name": "Elena Vaughn", "provider": "smtp", "status": "connected", "health": "healthy", "daily_limit": 30, "active": true }, "test": { "works": true, "message": "Sign-in worked for sending and for reading replies.", "smtp": { "works": true, "result": "signed_in", "message": "Sending works." }, "imap": { "works": true, "result": "signed_in", "message": "Reading replies works." } } } ``` It can answer with these errors (status and code): 401 unauthorized; 403 scope_missing, forbidden; 409 conflict, idempotency_conflict; 422 validation_error, sign_in_failed; 429 rate_limited. ### Connect many mailboxes `POST /api/v1/inboxes/smtp/bulk` Connects up to 25 mailboxes in one call, each with the same fields as a single connect. Every row gets its own result: `connected`, `failed` (with the reason) or `skipped` (for example past a free trial's 2 mailboxes). Rows are checked 5 at a time, so a full call can take a minute or two. Up to 500 rows an hour. | Cost | What it does | Key scopes | | --- | --- | --- | | Free | writes | argorant:manage_lists | Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `Idempotency-Key` | header | string | no | Any unique text up to 128 characters. A retry with the same key and the same body within 24 hours returns the first answer (with the header Idempotent-Replayed: true) instead of doing the work twice. The same key with another body answers 409 idempotency_conflict. | Body fields (JSON) | Field | Type | Required | Description | | --- | --- | --- | --- | | `mailboxes` | array of object | yes | 1 to 25 mailboxes, each with the fields of a single connect. | Example request ```bash curl -X POST "https://app.argorant.com/api/v1/inboxes/smtp/bulk" \ -H "Authorization: Bearer $ARGORANT_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{"mailboxes":[{"email":"elena@northgate-advisory.com","preset":"zoho","smtp_password":"app-password-1"},{"email":"mark@northgate-advisory.com","preset":"zoho","smtp_password":"app-password-2"}]}' ``` Example answer (200) ```json { "connected": 1, "failed": 1, "skipped": 0, "results": [ { "row": 1, "email": "elena@northgate-advisory.com", "status": "connected", "result": "signed_in", "message": "Sign-in worked for sending and for reading replies.", "inbox": { "email": "elena@northgate-advisory.com", "provider": "smtp", "status": "connected", "daily_limit": 25 } }, { "row": 2, "email": "mark@northgate-advisory.com", "status": "failed", "result": "wrong_password", "message": "The server says the username or password is wrong. Many providers need an app password here." } ] } ``` It can answer with these errors (status and code): 401 unauthorized; 403 scope_missing; 409 idempotency_conflict; 422 validation_error; 429 rate_limited. ### Domain endings on offer `GET /api/v1/inboxes/endings` The domain endings new mailboxes can be ordered on, such as com or co. | Cost | What it does | Key scopes | | --- | --- | --- | | Free | Reads only | argorant:manage_lists | Example request ```bash curl -X GET "https://app.argorant.com/api/v1/inboxes/endings" \ -H "Authorization: Bearer $ARGORANT_API_KEY" ``` Example answer (200) ```json { "endings": [ "com", "co", "io", "net" ] } ``` It can answer with these errors (status and code): 401 unauthorized; 403 scope_missing; 429 rate_limited. ### Suggest domain names `GET /api/v1/inboxes/domains/suggest` Free domain names for new sending mailboxes, made from your website or brand, each with its first-year and yearly renewal price in cents. Checks only; nothing is reserved or charged. | Cost | What it does | Key scopes | | --- | --- | --- | | Free | Reads only | argorant:manage_lists | Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `company` | query | string | yes | Your website or brand. | | `ending` | query | string | no | Only this ending, or all. | | `limit` | query | integer | no | Names to return, up to 60 (default 20). | Example request ```bash curl -X GET "https://app.argorant.com/api/v1/inboxes/domains/suggest?company=northgate-advisory.com&ending=com" \ -H "Authorization: Bearer $ARGORANT_API_KEY" ``` Example answer (200) ```json { "company": "northgate-advisory.com", "endings": [ "com", "co" ], "results": [ { "name": "getnorthgate.com", "available": true, "first_year": { "usd": 1499, "eur": 1499 }, "renewal": { "usd": 1499, "eur": 1499 } } ] } ``` It can answer with these errors (status and code): 401 unauthorized; 403 scope_missing; 422 validation_error; 429 rate_limited. ### Quote new mailboxes `POST /api/v1/inboxes/quote` Prices new mailboxes on their own new domains. Send `mailboxes` (rounded up to bundles of 100 on 2 domains) or `daily_volume` (cold emails a day, 5 per mailbox), plus the `domains` you want and a `company` to fill the missing names. The quote lists every domain with its price, the mailbox price, what is due today and what repeats, and holds for 24 hours. Nothing is ordered or charged. | Cost | What it does | Key scopes | | --- | --- | --- | | Free | Reads only | argorant:manage_lists | Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `Idempotency-Key` | header | string | no | Any unique text up to 128 characters. A retry with the same key and the same body within 24 hours returns the first answer (with the header Idempotent-Replayed: true) instead of doing the work twice. The same key with another body answers 409 idempotency_conflict. | Body fields (JSON) | Field | Type | Required | Description | | --- | --- | --- | --- | | `mailboxes` | integer | no | How many mailboxes. | | `daily_volume` | integer | no | Or cold emails a day to send. | | `domains` | array of string | no | Domains you want. | | `company` | string | no | Your website or brand, to suggest names. | | `currency` | string | no | usd or eur. One of usd, eur. | | `billing` | string | no | month or quarter (5% off the mailboxes). One of month, quarter. | Example request ```bash curl -X POST "https://app.argorant.com/api/v1/inboxes/quote" \ -H "Authorization: Bearer $ARGORANT_API_KEY" \ -H "Content-Type: application/json" \ -d '{"mailboxes":100,"company":"northgate-advisory.com","currency":"usd","billing":"month"}' ``` Example answer (200) ```json { "quote_id": "5b7e2d4a-1c3f-4e8a-9b6d-0a2c4e6f8b1d", "expires_at": "2026-10-08T10:12:37+00:00", "currency": "usd", "plan": { "mailboxes": 100, "domains": 2, "daily_capacity": 500 }, "domains": [ { "name": "getnorthgate.com", "available": true, "first_year_cents": 1499, "renewal_per_year_cents": 1499 } ], "mailboxes": { "quantity": 100, "billing": "month", "price_cents": 29000 }, "due_today_cents": 31398, "recurring_cents": 29000, "renewal_per_year_cents": 4998, "summary": "100 mailboxes on 2 new domains. Due today 313.98 USD, then 290.00 USD per month for the mailboxes.", "next_step": "Show this quote to the user in full and order only after their explicit yes.", "can_order": true } ``` It can answer with these errors (status and code): 401 unauthorized; 403 scope_missing; 409 not_enough_names, idempotency_conflict; 422 validation_error; 429 rate_limited. ### List mailbox orders `GET /api/v1/inboxes/orders` Every mailbox order of your workspace, newest first, with status, domains and mailboxes. | Cost | What it does | Key scopes | | --- | --- | --- | | Free | Reads only | argorant:manage_lists | Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `limit` | query | integer | no | Rows per page, 1 to 500 (default 500). | | `cursor` | query | string | no | The next_cursor of the previous page. Leave out for the first page. | | `offset` | query | integer | no | Rows to skip, as an alternative to cursor. | Example request ```bash curl -X GET "https://app.argorant.com/api/v1/inboxes/orders?limit=500" \ -H "Authorization: Bearer $ARGORANT_API_KEY" ``` Example answer (200) ```json { "orders": [ { "order_id": "b345aa96-059d-47e7-b733-c1899f843a00", "status": "aging", "mailboxes": { "created": 100, "total": 100 }, "daily_capacity": 500, "domains": [ { "name": "getnorthgate.com", "expires_at": "2027-09-27T10:31:00+00:00", "renewal_per_year_cents": 1499 } ] } ], "total": 1, "limit": 25, "offset": 0, "next_cursor": null, "has_more": false } ``` It can answer with these errors (status and code): 401 unauthorized; 403 scope_missing; 422 validation_error; 429 rate_limited. ### Order new mailboxes `POST /api/v1/inboxes/orders` Orders exactly what a quote showed. `confirmed: true` states that the person who pays said yes to the full quote. When the workspace allows purchases with its saved card, the card is charged within its limits; otherwise you get `checkout_url`, a payment page the person pays themselves. Nothing is bought before that payment. `senders` are the people the mailboxes send as. | Cost | What it does | Key scopes | | --- | --- | --- | | The quoted price, charged only after the person who pays confirmed | charges money | argorant:manage_lists | Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `Idempotency-Key` | header | string | no | Any unique text up to 128 characters. A retry with the same key and the same body within 24 hours returns the first answer (with the header Idempotent-Replayed: true) instead of doing the work twice. The same key with another body answers 409 idempotency_conflict. | Body fields (JSON) | Field | Type | Required | Description | | --- | --- | --- | --- | | `quote_id` | string | yes | The quote the person said yes to. | | `senders` | array of object | no | Names the mailboxes send as. | | `website` | string | no | Where visitors of the new domains go. | | `confirmed` | boolean | yes | true: the person who pays said yes. | | `pay_with` | string | no | auto or link. One of auto, link. | Example request ```bash curl -X POST "https://app.argorant.com/api/v1/inboxes/orders" \ -H "Authorization: Bearer $ARGORANT_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{"quote_id":"5b7e2d4a-1c3f-4e8a-9b6d-0a2c4e6f8b1d","senders":[{"first_name":"Elena","last_name":"Vaughn"}],"website":"northgate-advisory.com","confirmed":true}' ``` Example answer (201) ```json { "order_id": "b345aa96-059d-47e7-b733-c1899f843a00", "checkout_url": "https://checkout.example.com/pay/cs_live_a1B2c3", "status": "awaiting_payment", "existing": false, "message": "Send this checkout link to the user. Nothing is bought until they pay it; setup starts after the payment is confirmed." } ``` It can answer with these errors (status and code): 400 confirmation_required; 401 unauthorized; 403 scope_missing, owner_only; 409 idempotency_conflict; 410 quote_expired; 422 validation_error; 429 rate_limited. ### Get a mailbox order `GET /api/v1/inboxes/orders/{order_id}` One order with its status and setup step, each domain with its expiry and renewal price, mailboxes created of the total, when the 24-hour aging ends, and the billing with the mailbox bundles you can cancel. | Cost | What it does | Key scopes | | --- | --- | --- | | Free | Reads only | argorant:manage_lists | Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `order_id` | path | string | yes | The order id. | Example request ```bash curl -X GET "https://app.argorant.com/api/v1/inboxes/orders/b345aa96-059d-47e7-b733-c1899f843a00" \ -H "Authorization: Bearer $ARGORANT_API_KEY" ``` Example answer (200) ```json { "order_id": "b345aa96-059d-47e7-b733-c1899f843a00", "status": "ready", "mailboxes": { "created": 100, "total": 100 }, "daily_capacity": 500, "domains": [ { "name": "getnorthgate.com", "auto_renew": true, "renewal_action": "Stop renewal" } ], "billing": { "state": "active", "next_charge_at": "2026-10-27T10:13:00+00:00", "bundles": [ { "bundle_id": "c1f0a3e2-7d4b-4a9e-8f21-6b3d5e7a9c10", "mailboxes": 100, "status": "active" } ], "can_cancel": true } } ``` It can answer with these errors (status and code): 401 unauthorized; 403 scope_missing; 404 not_found; 429 rate_limited. ### Cancel a bundle of mailboxes `POST /api/v1/inboxes/orders/{order_id}/bundles/{bundle_id}/cancel` Billing for the bundle stops now, without a refund. The mailboxes keep working until the paid period ends, then they are deleted. Their domains stop renewing too unless `keep_domains` is true. A reason is required. Only the workspace owner can cancel. | Cost | What it does | Key scopes | | --- | --- | --- | | Free | writes | argorant:manage_lists | Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `order_id` | path | string | yes | The order id. | | `bundle_id` | path | string | yes | From billing.bundles of the order. | | `Idempotency-Key` | header | string | no | Any unique text up to 128 characters. A retry with the same key and the same body within 24 hours returns the first answer (with the header Idempotent-Replayed: true) instead of doing the work twice. The same key with another body answers 409 idempotency_conflict. | Body fields (JSON) | Field | Type | Required | Description | | --- | --- | --- | --- | | `reason` | string | yes | Why, one of the reasons the order status lists in billing.cancel_reasons. | | `keep_domains` | boolean | no | Keep renewing the domains. | | `note` | string | no | More words, up to 1,000 characters. | Example request ```bash curl -X POST "https://app.argorant.com/api/v1/inboxes/orders/b345aa96-059d-47e7-b733-c1899f843a00/bundles/c1f0a3e2-7d4b-4a9e-8f21-6b3d5e7a9c10/cancel" \ -H "Authorization: Bearer $ARGORANT_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{"reason":"too_expensive","keep_domains":false}' ``` Example answer (200) ```json { "bundle_id": "c1f0a3e2-7d4b-4a9e-8f21-6b3d5e7a9c10", "mailboxes": 100, "ends_at": "2026-10-27T10:13:00+00:00", "status": "requested", "existing": false, "message": "Billing for these mailboxes stopped. They keep working until ends_at, then they are deleted; their domains do not renew." } ``` It can answer with these errors (status and code): 401 unauthorized; 403 scope_missing, owner_only; 404 not_found; 409 not_paid, idempotency_conflict; 422 validation_error, reason_required; 429 rate_limited. ### Turn a domain's renewal off or on `POST /api/v1/inboxes/orders/{order_id}/domains/{domain}/renewal` `on: false` stops the renewal. The domain then works until its expiry date and is never deleted early. `on: true` turns the renewal back on, so it renews at its expiry, billed shortly before. Nothing is charged now either way. | Cost | What it does | Key scopes | | --- | --- | --- | | Free | writes | argorant:manage_lists | Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `order_id` | path | string | yes | The order id. | | `domain` | path | string | yes | One domain of the order. | | `Idempotency-Key` | header | string | no | Any unique text up to 128 characters. A retry with the same key and the same body within 24 hours returns the first answer (with the header Idempotent-Replayed: true) instead of doing the work twice. The same key with another body answers 409 idempotency_conflict. | Body fields (JSON) | Field | Type | Required | Description | | --- | --- | --- | --- | | `on` | boolean | yes | true: renew. false: stop renewal. | Example request ```bash curl -X POST "https://app.argorant.com/api/v1/inboxes/orders/b345aa96-059d-47e7-b733-c1899f843a00/domains/trynorthgate.co/renewal" \ -H "Authorization: Bearer $ARGORANT_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{"on":false}' ``` Example answer (200) ```json { "domain": "trynorthgate.co", "renewal": "off", "auto_renew": false, "expires_at": "2027-09-27T10:33:00+00:00", "message": "Nothing is charged now. trynorthgate.co will not renew. It keeps working until September 27, 2027, then its mailboxes stop.", "next_action": "Turn renewal back on" } ``` It can answer with these errors (status and code): 401 unauthorized; 403 scope_missing; 404 not_found; 409 idempotency_conflict; 422 validation_error; 429 rate_limited. ### List webhooks `GET /api/v1/webhooks` Your webhooks and the events you can subscribe to. | Cost | What it does | Key scopes | | --- | --- | --- | | Free | Reads only | argorant:read_counts | Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `limit` | query | integer | no | Rows per page, 1 to 100 (default 25). | | `cursor` | query | string | no | The next_cursor of the previous page. Leave out for the first page. | | `offset` | query | integer | no | Rows to skip, as an alternative to cursor. | Example request ```bash curl -X GET "https://app.argorant.com/api/v1/webhooks?limit=25" \ -H "Authorization: Bearer $ARGORANT_API_KEY" ``` Example answer (200) ```json { "events": [ "export.ready", "verification.completed", "segment.new_matches", "reply.received", "reply.positive", "email.bounced", "email.unsubscribed", "campaign.paused", "campaign.resumed", "list.ready" ], "webhooks": [ { "id": "41", "url": "https://hooks.example.com/argorant", "events": [ "reply.positive" ], "active": true, "failure_count": 0, "last_error": null, "last_success_at": "2026-10-07T09:05:01+00:00", "created_at": "2026-10-07T09:00:00+00:00" } ], "total": 1, "limit": 25, "offset": 0, "next_cursor": null, "has_more": false } ``` It can answer with these errors (status and code): 401 unauthorized; 403 scope_missing; 422 validation_error; 429 rate_limited. ### Create a webhook `POST /api/v1/webhooks` Argorant calls your HTTPS URL when one of the events happens. The answer holds a signing secret, shown only once: every call carries `X-Argorant-Signature: sha256=`, the HMAC-SHA256 of the raw body with that secret. Up to 10 webhooks per account, switched off ones included. Campaign events reach the webhooks of the workspace owner and of every active team member; exports, lists and checks reach the person who started them. Included from the Pro plan. | Cost | What it does | Key scopes | | --- | --- | --- | | Free, from the Pro plan | writes | argorant:manage_lists | Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `Idempotency-Key` | header | string | no | Any unique text up to 128 characters. A retry with the same key and the same body within 24 hours returns the first answer (with the header Idempotent-Replayed: true) instead of doing the work twice. The same key with another body answers 409 idempotency_conflict. | Body fields (JSON) | Field | Type | Required | Description | | --- | --- | --- | --- | | `url` | string | yes | Your HTTPS endpoint on the public internet. | | `events` | array of WebhookEvent | yes | Events to receive. | Example request ```bash curl -X POST "https://app.argorant.com/api/v1/webhooks" \ -H "Authorization: Bearer $ARGORANT_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{"url":"https://hooks.example.com/argorant","events":["reply.positive","email.bounced"]}' ``` Example answer (201) ```json { "id": "41", "url": "https://hooks.example.com/argorant", "events": [ "reply.positive", "email.bounced" ], "secret": "whsec_3f9c2a7b1d4e5f60718293a4b5c6d7e8f9a0b1c2d3e4f5a6", "note": "Store this signing secret now. It is only shown once. Each delivery carries X-Argorant-Signature, which is sha256= followed by the hex HMAC-SHA256 of the raw body with this secret." } ``` It can answer with these errors (status and code): 400 invalid_webhook_url, invalid_request; 401 unauthorized; 402 plan_required; 403 scope_missing; 409 idempotency_conflict; 422 validation_error; 429 rate_limited. ### Change a webhook `PATCH /api/v1/webhooks/{webhook_id}` Change the URL, the events, or switch it off and on. Only the fields you send change. | Cost | What it does | Key scopes | | --- | --- | --- | | Free | writes | argorant:manage_lists | Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `webhook_id` | path | integer | yes | The webhook id. | | `Idempotency-Key` | header | string | no | Any unique text up to 128 characters. A retry with the same key and the same body within 24 hours returns the first answer (with the header Idempotent-Replayed: true) instead of doing the work twice. The same key with another body answers 409 idempotency_conflict. | Body fields (JSON) | Field | Type | Required | Description | | --- | --- | --- | --- | | `url` | string | no | New URL. | | `events` | array of WebhookEvent | no | New events. | | `active` | boolean | no | On or off. | Example request ```bash curl -X PATCH "https://app.argorant.com/api/v1/webhooks/41" \ -H "Authorization: Bearer $ARGORANT_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{"active":false}' ``` Example answer (200) ```json { "webhook": { "id": "41", "url": "https://hooks.example.com/argorant", "events": [ "reply.positive" ], "active": false, "failure_count": 0, "last_error": null, "last_success_at": null, "created_at": "2026-10-07T09:00:00+00:00" } } ``` It can answer with these errors (status and code): 401 unauthorized; 403 scope_missing; 404 not_found; 409 idempotency_conflict; 422 validation_error; 429 rate_limited. ### Delete a webhook `DELETE /api/v1/webhooks/{webhook_id}` Stops and deletes the webhook. | Cost | What it does | Key scopes | | --- | --- | --- | | Free | writes | argorant:manage_lists | Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `webhook_id` | path | integer | yes | The webhook id. | | `Idempotency-Key` | header | string | no | Any unique text up to 128 characters. A retry with the same key and the same body within 24 hours returns the first answer (with the header Idempotent-Replayed: true) instead of doing the work twice. The same key with another body answers 409 idempotency_conflict. | Example request ```bash curl -X DELETE "https://app.argorant.com/api/v1/webhooks/41" \ -H "Authorization: Bearer $ARGORANT_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" ``` Example answer (200) ```json { "deleted": true, "webhook_id": 41 } ``` It can answer with these errors (status and code): 401 unauthorized; 403 scope_missing; 404 not_found; 409 idempotency_conflict; 429 rate_limited. ### Send a test event `POST /api/v1/webhooks/{webhook_id}/test` Sends one signed test call to the webhook's URL. See the result under deliveries. | Cost | What it does | Key scopes | | --- | --- | --- | | Free | writes | argorant:manage_lists | Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `webhook_id` | path | integer | yes | The webhook id. | | `Idempotency-Key` | header | string | no | Any unique text up to 128 characters. A retry with the same key and the same body within 24 hours returns the first answer (with the header Idempotent-Replayed: true) instead of doing the work twice. The same key with another body answers 409 idempotency_conflict. | Example request ```bash curl -X POST "https://app.argorant.com/api/v1/webhooks/41/test" \ -H "Authorization: Bearer $ARGORANT_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{}' ``` Example answer (200) ```json { "queued_delivery_id": "9012", "event": "reply.positive" } ``` It can answer with these errors (status and code): 401 unauthorized; 403 scope_missing; 404 not_found; 409 idempotency_conflict; 429 rate_limited. ### Webhook deliveries `GET /api/v1/webhooks/{webhook_id}/deliveries` Recent calls to the webhook with their result, tries and the next try. Failed calls are retried with growing pauses. | Cost | What it does | Key scopes | | --- | --- | --- | | Free | Reads only | argorant:read_counts | Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `webhook_id` | path | integer | yes | The webhook id. | | `limit` | query | integer | no | Rows per page, 1 to 100 (default 25). | | `cursor` | query | string | no | The next_cursor of the previous page. Leave out for the first page. | | `offset` | query | integer | no | Rows to skip, as an alternative to cursor. | Example request ```bash curl -X GET "https://app.argorant.com/api/v1/webhooks/41/deliveries?limit=25" \ -H "Authorization: Bearer $ARGORANT_API_KEY" ``` Example answer (200) ```json { "deliveries": [ { "id": "9012", "event": "reply.positive", "status": "delivered", "status_code": 200, "attempts": 1, "last_error": null, "created_at": "2026-10-07T09:05:00+00:00", "delivered_at": "2026-10-07T09:05:01+00:00", "next_attempt_at": null } ], "total": null, "limit": 25, "offset": 0, "next_cursor": null, "has_more": false } ``` It can answer with these errors (status and code): 401 unauthorized; 403 scope_missing; 404 not_found; 422 validation_error; 429 rate_limited. ### List connected tools `GET /api/v1/integrations` The tools connected in Settings, Connected tools, with the id to use in the calls below. can_receive_people is true for the sending tools that take a campaign's people or an export directly. | Cost | What it does | Key scopes | | --- | --- | --- | | Free | Reads only | argorant:read_counts | Example request ```bash curl -X GET "https://app.argorant.com/api/v1/integrations" \ -H "Authorization: Bearer $ARGORANT_API_KEY" ``` Example answer (200) ```json { "integrations": [ { "id": "18", "tool": "sending_tool", "name": "Your sending tool", "can_receive_people": true, "connected_at": "2026-10-01T09:00:00+00:00" } ] } ``` It can answer with these errors (status and code): 401 unauthorized; 403 scope_missing; 429 rate_limited. ### Campaigns in a connected tool `GET /api/v1/integrations/{integration_id}/campaigns` The campaigns in your account of that tool, so you can pick where people go. Archived campaigns are left out. Use the id as target_campaign_id when you send. | Cost | What it does | Key scopes | | --- | --- | --- | | Free | Reads only | argorant:read_counts | Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `integration_id` | path | integer | yes | The connected tool's id from GET /api/v1/integrations. | Example request ```bash curl -X GET "https://app.argorant.com/api/v1/integrations/18/campaigns" \ -H "Authorization: Bearer $ARGORANT_API_KEY" ``` Example answer (200) ```json { "integration_id": "18", "tool": "sending_tool", "campaigns": [ { "id": "3356753", "name": "Q4 CFO follow-up", "status": "DRAFTED" } ] } ``` It can answer with these errors (status and code): 401 unauthorized; 403 scope_missing; 404 not_found; 409 unsupported_tool, tool_key_rejected; 429 rate_limited. ### Send people to a connected tool `POST /api/v1/integrations/{integration_id}/pushes` Sends the people of one of your Argorant campaigns, or the rows of one of your exports, into a campaign in the connected tool. Send campaign_id or export_id, not both. People who bounced, unsubscribed or are on your blocklist are never sent. An export that is still being built is fine: the people go as soon as the file is ready. To send a list, export it first (POST /api/v1/lists/{list_id}/export) and send that export. Up to 100,000 people per call. The campaign in the tool is not started and no email is sent. The answer is the push; read its progress with GET /api/v1/integrations/pushes/{push_id}. | Cost | What it does | Key scopes | | --- | --- | --- | | Free, from the Pro plan. Exports are paid when they run. | writes | argorant:manage_lists | Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `integration_id` | path | integer | yes | The connected tool's id from GET /api/v1/integrations. | | `Idempotency-Key` | header | string | no | Any unique text up to 128 characters. A retry with the same key and the same body within 24 hours returns the first answer (with the header Idempotent-Replayed: true) instead of doing the work twice. The same key with another body answers 409 idempotency_conflict. | Body fields (JSON) | Field | Type | Required | Description | | --- | --- | --- | --- | | `campaign_id` | string | no | Send the people of one of your Argorant campaigns. | | `export_id` | integer | no | Send the rows of one of your exports. It may still be running. | | `target_campaign_id` | string | yes | The campaign in the tool, from GET /api/v1/integrations/{integration_id}/campaigns. | | `results` | array of string | no | For an export, which email results to send, from valid, catch_all and risky. Default valid. | | `only_not_contacted` | boolean | no | For a campaign, send only people who were not emailed yet. Default false. | Example request ```bash curl -X POST "https://app.argorant.com/api/v1/integrations/18/pushes" \ -H "Authorization: Bearer $ARGORANT_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{"campaign_id":"7f3a2c1e-9b4d-4e8a-a1c2-5d6e7f8a9b0c","target_campaign_id":"3356753","only_not_contacted":true}' ``` Example answer (202) ```json { "push_id": "912", "tool": "sending_tool", "tool_name": "Your sending tool", "integration_id": "18", "source": { "kind": "campaign", "id": "7f3a2c1e-9b4d-4e8a-a1c2-5d6e7f8a9b0c" }, "target_campaign_id": "3356753", "status": "queued", "total": 0, "sent": 0, "already_there": 0, "not_accepted": 0, "message": "Sending to your sending tool.", "created_at": "2026-10-12T09:00:00+00:00", "completed_at": null } ``` It can answer with these errors (status and code): 401 unauthorized; 402 plan_required; 403 scope_missing; 404 not_found; 409 unsupported_tool, export_failed, idempotency_conflict; 422 validation_error, invalid_request; 429 rate_limited. ### Progress of a send `GET /api/v1/integrations/pushes/{push_id}` Shows how a send stands (waiting_for_export, queued, sending, done or failed) and how many people were sent, were already in the tool's campaign, or were not accepted there. | Cost | What it does | Key scopes | | --- | --- | --- | | Free | Reads only | argorant:read_counts | Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `push_id` | path | integer | yes | The push id from the send. | Example request ```bash curl -X GET "https://app.argorant.com/api/v1/integrations/pushes/912" \ -H "Authorization: Bearer $ARGORANT_API_KEY" ``` Example answer (200) ```json { "push_id": "912", "tool": "sending_tool", "tool_name": "Your sending tool", "integration_id": "18", "source": { "kind": "campaign", "id": "7f3a2c1e-9b4d-4e8a-a1c2-5d6e7f8a9b0c" }, "target_campaign_id": "3356753", "status": "done", "total": 412, "sent": 398, "already_there": 14, "not_accepted": 0, "message": "398 sent, 14 already there, 0 not accepted. The campaign in the tool was not started and no email was sent.", "created_at": "2026-10-12T09:00:00+00:00", "completed_at": "2026-10-12T09:01:40+00:00" } ``` It can answer with these errors (status and code): 401 unauthorized; 403 scope_missing; 404 not_found; 429 rate_limited. ## MCP tools in detail ### argorant_account Check account and limits. Show who is connected, how many credits are left and how much of today's limits is used. role is the user's role in the workspace (owner, admin, manager or member). The credits left are in contact_credits. Credits pay for revealing people and for adding new people to a campaign. Daily limits are safety limits. They cost nothing and are separate from credits. The result's summary says all of this in plain words. This is not a price quote. Checking the account is free. More in the docs at https://docs.argorant.com/docs/agents/tools#read-and-preview ### argorant_add_campaign_leads Add leads to a campaign. This spends credits. Each new person from Argorant costs 1 credit, like a reveal, so ask the user before adding. Add people to a campaign from a saved list (list_id from argorant_create_list) or from rows the user gives you, [{email, first_name?, last_name?, company?, title?}]. Ask the user before adding, every time. First call it WITHOUT grades. If the list holds anything besides valid addresses, the result is needs_choice. It has the count for each kind of address, a question and a plain explanation of each kind, and nothing is added yet. Put the question to the user right away, in the words of the result's question field. Offer the other kinds with their counts too. If the user asks what they mean, use the explanations. Catch-all means the company's domain accepts every address, so this one cannot be confirmed. Unknown means the check got no clear answer for this address. Risky means there are signs of a bad or temporary address. Each of these bounces more often than a valid address, and bounces hurt the sender's reputation. Recommend valid only. Then call again with grades=["valid"] (recommended) or ["valid", "catch_all"]. That choice is also saved for the campaign. Unknown and risky addresses cannot be sent to yet, and invalid addresses are never added. The same person under two addresses joins once, and the address already in the campaign stays. Each new person from Argorant costs 1 credit, like a reveal. People already unlocked, people already in the campaign and the user's own rows are free. If credits run out, the first people are added and the rest are reported as left out. Tell the user the cost before adding a large list. argorant_account shows the credits left. Nothing is scheduled or sent until the campaign is launched. Adding a list again later adds only the people who are not in the campaign yet. So "add the rest" means adding the rest of the search to the SAME list (argorant_create_list with its list_id), then calling this again with that list_id. Never create a second list for it. The result's summary says where every person on the list went (added, already in the campaign, the same person twice, blocked, catch-all, invalid, unconfirmed or no usable email). Tell the user what it says instead of reading out the raw numbers. Addresses that are not checked yet are checked in the background and join if they match the choice. Call again later to see them counted. More in the docs at https://docs.argorant.com/docs/agents/tools#campaigns ### argorant_block Block an address or domain. Never contact this email address or domain again. Matching people in campaigns stop getting emails at once. More in the docs at https://docs.argorant.com/docs/agents/tools#analytics-mailbox-settings-blocklist ### argorant_blocklist Read the blocklist. List the email addresses and domains this workspace never contacts. More in the docs at https://docs.argorant.com/docs/agents/tools#analytics-mailbox-settings-blocklist ### argorant_buy_credits Buy the quoted credit pack. Buy exactly the credit pack of one quote from argorant_quote_credits. Show the user the pack, the price and the currency, and how it will be paid, and buy only after their explicit yes. Set confirmed=true only with that yes, and put the user's own words that said yes in user_confirmation: they are recorded with the purchase. Through Claude or ChatGPT, this always returns checkout_url, a payment link the user opens and pays themselves, and a saved card is never charged. Through an API key or another app, when the quote said the saved card is usable, this call charges that card right away, so tell the user which card and how much before they say yes. Otherwise it returns checkout_url, which is a payment link the user pays themselves, and you tell the user any reason given. You never enter card details or open, complete or pay a payment page. The credits are added once the payment went through. Repeating the same call returns the same purchase and never charges twice. pay_with=link always returns a payment link. Never retry with a new quote to get around a limit or a refusal. More in the docs at https://docs.argorant.com/docs/agents/tools#credits ### argorant_campaign_analytics Campaign analytics over time. Show one campaign day by day, with emails sent, replies, positive replies, bounces and unsubscribes, plus totals and the reply and bounce rates. days sets how many days to show (30 by default). variants shows the results of every version of each email, the main text and its variants, with sends, replies, replies from people (out of office left out), positive replies and their rates. A version is marked as leader only once at least two versions have sends and one has a positive reply. Differences under about 200 sends per version are mostly chance. Versions marked removed are no longer sent, and the row written per contact counts emails sent with each contact's own written text. More in the docs at https://docs.argorant.com/docs/agents/tools#analytics-mailbox-settings-blocklist ### argorant_campaign_personalization_status Personalization progress and the next contacts. Show how many of the campaign's personal lines are written. It lists the variables with their fallbacks, how many contacts have their own line, and the next contacts still on the fallback, up to pending_limit, with the ones sent first at the top. Each comes with its lead_id and what Argorant knows about the company (description, industry, category, keywords, location, size). Write their lines from those facts, or from the company's website, with argorant_set_lead_custom_fields. Then call this again for the next contacts. written_sample shows lines saved recently. More in the docs at https://docs.argorant.com/docs/agents/tools#campaigns ### argorant_cancel_inbox_bundle Cancel a bundle of mailboxes. Cancel one bundle of mailboxes (bundle_id from argorant_inbox_order_status). Billing for them stops now, with no refund. They keep working until the paid period ends and are then deleted for good. Their domains stop renewing too, unless keep_domains=true. Ask the user for explicit approval first, and ask why. reason is required and must be one of too_expensive (Too expensive); not_sending_enough (Not sending enough); deliverability (Deliverability problems); switching_provider (Switching to another provider); campaign_finished (Campaign finished); other (Other). note is optional. Only the workspace owner can cancel. Sending it again returns the first cancellation. More in the docs at https://docs.argorant.com/docs/agents/tools#new-inboxes ### argorant_cancel_inbox_domain Stop a domain's renewal (old name). This is the old name for argorant_set_inbox_domain_renewal with on=false. Use that tool instead. It stops renewal for one ordered domain. The domain keeps working until its expiry date and is not renewed or charged again. Nothing is charged now. Domains are never deleted early. Ask the user for explicit approval first. Only the workspace owner can change it. More in the docs at https://docs.argorant.com/docs/agents/tools#new-inboxes ### argorant_company_people Find people at a company. Show how many people Argorant has at one company domain. This is not the company's total staff. Returns how many of them have a work email, facts about the company and a few example rows with job titles, names hidden. Use this rather than putting a domain into a free-text search. It takes the same people filters as argorant_count_people, include and exclude alike. It shows no contact details and costs no credits. It counts toward the daily limits, which are safety limits and cost nothing. More in the docs at https://docs.argorant.com/docs/agents/tools#read-and-preview ### argorant_connect_google_workspace Connect Google Workspace mailboxes. Connect Google Workspace mailboxes in two steps. First call it without emails. It returns the client ID and the list of permissions that the Workspace admin pastes in Google Admin > Security > API controls > Domain-wide delegation. Once the admin has done that, the same call lists every mailbox and alias in the Workspace. Then call it again with emails, or with an empty list for all of them, to connect those addresses as sending mailboxes. No passwords are needed and nobody has to sign in to each mailbox. More in the docs at https://docs.argorant.com/docs/agents/tools#mailboxes ### argorant_connect_smtp_mailbox Connect a mailbox from any provider. Connect a mailbox from any email provider, such as Zoho, Fastmail, Yahoo, iCloud, IONOS or your web host, so campaigns can send from it and its replies arrive in Argorant. Give one mailbox, or up to 25 at once in mailboxes. Argorant first signs in to send and to read replies, and connects only the mailboxes where both work. A mailbox that does not sign in comes back with the reason in plain words and is not connected. Connecting the same address again replaces its saved settings, which is how a mailbox is reconnected after a password change. The password is stored safely and never shown again. Many providers need an app password instead of the normal one. A free trial connects up to 2 mailboxes. Google and Microsoft mailboxes connect with their own sign-in instead (argorant_connect_google_workspace, or the Mailboxes page in Argorant). Test the mailbox with the sign-in test tool first when the settings are uncertain. Connecting is free and sends no email. Through Claude, never ask for a mailbox password: this returns connect_url, the link to Argorant's own mailbox form, where the user enters the password and the mailbox is tested and connected. More in the docs at https://docs.argorant.com/docs/agents/tools#mailboxes ### argorant_count_people Count matching people. Count the people in Argorant who match a search by company, job title, seniority, department, industry, keywords or place. The number counts people, not companies, and it is not a company's total staff. It costs no credits. It counts toward a daily limit, which is a safety limit and costs nothing. Use keywords for words that describe what the company does, such as MSP or freight forwarding; a comma means any of them. Use industry for broad sectors. Plain words such as logistics, healthcare or law firms are matched to Argorant's industries, and other words are matched as keywords. The result's industry_note says how the word was read. Check that the search finds the right people with argorant_preview_people. country takes countries or regions such as Europe, EMEA, DACH, Nordics, Benelux, APAC, LATAM, North America or GCC, and you can list several with commas. geography does the same. title understands short forms both ways, so CFO also finds Chief Financial Officer. List several titles with commas to match any of them. exclude_title leaves roles out in the same way. Every list filter has a matching exclude filter, such as exclude_title, exclude_keywords, exclude_industry, exclude_country, exclude_seniority, exclude_departments or exclude_company_domain. Include and exclude work together, and a comma means any of them. Keywords look at what the company does, that is its name, tags, industry and description. Set them to look at people's own skills only when the user wants people who have a skill themselves, such as people who know Python, or at both. Job titles match whole words unless you choose exact roles or contains with title_match. Employee and revenue ranges work the same way everywhere. To find companies by who they sell to, set company_category (software, payments, pos_payments, business_fintech, accounting_software, payroll_hr_software, formation, association, marketplace, investors) and sells_to (restaurants, construction, dentists, salons, auto_repair, hotels, logistics, trades, retailers, smb), or write it in q, for example "software companies selling to restaurants". That returns the companies that sell, never their customers. More in the docs at https://docs.argorant.com/docs/agents/tools#read-and-preview ### argorant_create_campaign Create an email campaign (draft). Create a new campaign as a draft. Nothing is sent until argorant_launch_campaign. Next, add the emails with argorant_set_campaign_emails, the people with argorant_add_campaign_leads and the sending mailboxes with argorant_set_campaign_senders. The gap is a random number of minutes between two emails from the same mailbox. 60 to 120 minutes is the safe default for Microsoft mailboxes. New campaigns start with bounce protection and stop on reply switched on. argorant_update_campaign changes both. More in the docs at https://docs.argorant.com/docs/agents/tools#campaigns ### argorant_create_export Create a CSV export. Create a spreadsheet file (CSV) of the people who match a search. A large search is split into several files. Each person with a working email costs 1 credit. People who were exported before are skipped unless exclude_previously_exported is false. Phone numbers are only included when include_phones is true. They cost 10 credits per phone number returned, nothing if none is found. Ask the user before spending. Phone numbers need the Pro plan or higher. Tell the user what it can cost and get their approval before you start. The file is made in the background; check it with argorant_export_status, or argorant_export_batch_status when it is split into several files. email_when_done asks Argorant to email the user when the file is ready. Asking again can start a second export. It takes the same filters as argorant_count_people, include and exclude alike. A search that leaves people out, picks how titles or keywords match, or uses the gender, income, range or place filters can export up to 50,000 people at a time; for more, save it as a list with argorant_create_list and export that list with argorant_export_list. More in the docs at https://docs.argorant.com/docs/agents/tools#reveal-enrich-export ### argorant_create_list Save a lead list. Save a lead list, or add people to a list the user already has. By default it saves the WHOLE search. Pass the same filters you counted or previewed with, and every match is saved. Saved people stay hidden until they are revealed or added to a campaign. When the user says "save them as a list" after a preview, they mean the whole search. Only when the user clearly wants just the people shown, pass their record_ids with only_these=true. To grow a list, pass its list_id. The search, or the record_ids, are added, and people already in the list are skipped. "Add the rest" means the same search into the SAME list_id, then argorant_add_campaign_leads with that list again. Never create a second list for the rest. The result's summary says how many people were added and how many were already there. Tell the user. Saving is free, shows no contact details and sends nothing. The list is private and is not published. Calling it again can create a second list. Every list filter has a matching exclude filter, such as exclude_title, exclude_keywords, exclude_industry, exclude_country, exclude_seniority, exclude_departments or exclude_company_domain. Include and exclude work together, and a comma means any of them. Keywords look at what the company does, that is its name, tags, industry and description. Set them to look at people's own skills only when the user wants people who have a skill themselves, such as people who know Python, or at both. Job titles match whole words unless you choose exact roles or contains with title_match. Employee and revenue ranges work the same way everywhere. A saved search, and every add to a list, is filled in the background and answers at once; an add to a list that is still filling waits its turn and is never dropped. argorant_list_status shows when the list is ready. More in the docs at https://docs.argorant.com/docs/agents/tools#lists ### argorant_create_reply_status Add a reply label. Create one of the workspace's own reply labels, for example 'Pricing question' or 'Proposal sent'. This is what a user means by 'create a new classification'. Give a one-line description of when a reply fits. color can be lime, blue, purple, yellow, rose or neutral. Renaming, hiding and deleting labels is done in Settings. More in the docs at https://docs.argorant.com/docs/agents/tools#inbox ### argorant_create_webhook Add a webhook. Have Argorant send a notification to a public https address the user names whenever one of the chosen events happens, for example reply.received or export.ready (argorant_webhooks lists them all). Webhooks come with the Pro plan. The result shows the signing secret once, so give it to the user. Ask the user for explicit approval first. It is free. More in the docs at https://docs.argorant.com/docs/agents/tools#webhooks and https://docs.argorant.com/docs/guides/webhooks ### argorant_credit_packs Credit packs and prices. Show the credit packs the user can buy once, without a subscription, with their prices. 1 credit buys 1 validated contact, and half a credit checks one email from the user's own list. Pack credits stay valid for 365 days. Use it before argorant_quote_credits. It is free, only reads and changes nothing. More in the docs at https://docs.argorant.com/docs/agents/tools#credits ### argorant_credit_purchases Check credit purchases. Show the credit packs bought through the API or an assistant, or one purchase when you pass purchase_id. Each one shows the pack, the amount, how it was paid (saved card or payment link) and whether the credits were added. It is free, only reads and changes nothing. More in the docs at https://docs.argorant.com/docs/agents/tools#credits ### argorant_delete_campaign Delete a campaign. Delete a draft, paused or stopped campaign, together with its emails, people and results. A running campaign must be stopped first. Ask the user before you call this. More in the docs at https://docs.argorant.com/docs/agents/tools#campaigns ### argorant_delete_list Delete a saved list. Delete a saved list or saved search for good. Exports already made from it and people already in campaigns stay. It cannot be undone. Ask the user for explicit approval first, and set confirmed=true only with that yes. It is free. More in the docs at https://docs.argorant.com/docs/agents/tools#lists ### argorant_delete_reply_status Delete a reply label. Delete one of the workspace's own reply labels. Replies that carried it go back to Other. Standard labels cannot be deleted, so hide them with argorant_update_reply_status instead. Ask the user for explicit approval first, and set confirmed=true only with that yes. It is free. More in the docs at https://docs.argorant.com/docs/agents/tools#inbox ### argorant_delete_webhook Delete a webhook. Stop sending events to one webhook (its id comes from argorant_webhooks). Ask the user for explicit approval first, and set confirmed=true only with that yes. It is free. More in the docs at https://docs.argorant.com/docs/agents/tools#webhooks and https://docs.argorant.com/docs/guides/webhooks ### argorant_disconnect_inbox Disconnect a mailbox. Disconnect one connected mailbox from Argorant. It is taken off every campaign and nothing more is sent from it. The mailbox and its emails are not deleted, Argorant just stops using it. Mailboxes ordered from Argorant keep being billed until they are cancelled with argorant_cancel_inbox_bundle. To pause a mailbox instead, use argorant_update_inbox with active=false. Ask the user for explicit approval first, and set confirmed=true only with that yes. It is free. More in the docs at https://docs.argorant.com/docs/agents/tools#mailboxes ### argorant_download_export_preview Read part of an export file. Read the first part of a finished export file (CSV) as plain text, up to max_characters (1,000 to 50,000). The text can stop in the middle of a row. Nothing is hidden, so it can show names, emails and other contact details. It is free and starts no new export. For the whole file, the user downloads it in Argorant. More in the docs at https://docs.argorant.com/docs/agents/tools#reveal-enrich-export ### argorant_enrich Enrich a person or company. Look up one person or one company. Give an email address, or a person's name together with their company's website domain, or a company domain on its own. Use one of these at a time; an email wins if you give several. A name finds the closest match at that company, so check the result before you rely on it. A person lookup shows their work email and costs 1 credit when the email is working and new to this account. It is free when nothing is found or when this account already has that email. Phone numbers are only included when include_phones is true. They cost 10 credits per phone number returned, nothing if none is found. Ask the user before spending. A company domain on its own is free and returns the company profile without any contact details. This is not a tool for checking the user's own email list. More in the docs at https://docs.argorant.com/docs/agents/tools#reveal-enrich-export ### argorant_export_batch_status Check several exports. Show how far an export that was split into several files has come, with the state of each file. It is free, starts no new export and sends no email. More in the docs at https://docs.argorant.com/docs/agents/tools#reveal-enrich-export ### argorant_export_list Export a saved list. Create a spreadsheet file (CSV) of a saved list. Each person with a working email costs 1 credit. People who were exported before are skipped unless exclude_previously_exported is false. Phone numbers are only included when include_phones is true. They cost 10 credits per phone number returned, nothing if none is found. Ask the user before spending. Phone numbers need the Pro plan or higher. Tell the user what it can cost and get their approval before you start. The file is made in the background; check it with argorant_export_status. email_when_done asks Argorant to email the user when the file is ready. More in the docs at https://docs.argorant.com/docs/agents/tools#lists ### argorant_export_status Check an export. Show how far an export started here has come and whether its file is ready. It is free, starts no new export and sends no email. More in the docs at https://docs.argorant.com/docs/agents/tools#reveal-enrich-export ### argorant_find_email Find a person's work email. Find one person's work email from their first name, last name and company domain. Use it when the user names a specific person at a specific company. To search for people by job, industry or place, use argorant_preview_people and argorant_reveal_people instead. To check addresses the user already has, use the email verification tools. Each person costs 1 credit when an email is found and confirmed, and 1 credit when the company's domain accepts every address (catch-all). In that case the most likely address is returned and marked unconfirmed. It costs 0.25 credits when nothing is found. Nothing is charged for invalid input, for a domain that does not exist or cannot receive email, or when the check cannot be finished right now (status retry_later). Credits are the account's shared credits. Every call is charged by its result, so ask the user before you spend credits and tell them the price. Never repeat a lookup that already returned not_found, and never loop over many people with this tool. For more than 5 people, use argorant_find_emails. Each address is checked live. Each account can do about 30 lookups a minute and 2,000 a day. These are safety limits and cost nothing. An account whose lookups almost never find anything is slowed down (rate_limited with retry_after_seconds), never charged more. The status is valid when the email was found and confirmed, so it is safe to use. It is catch_all when the company's domain accepts every address. That address is the best guess but unconfirmed, and it may bounce. The other statuses are not_found, no_mail_domain and retry_later. Tell the user which addresses are unconfirmed. Returns email, status, confirmed, confidence (0 to 100), credits_charged, the credits left and a plain message to pass on to the user. More in the docs at https://docs.argorant.com/docs/agents/tools#find-work-emails ### argorant_find_emails Find work emails for a list of people. Find work emails for a list of up to 1,000 people per call. Each person needs a first name, last name and company domain, and can carry your own ref. The list runs in the background. Each person costs 1 credit when an email is found and confirmed, and 1 credit when the company's domain accepts every address (catch-all). In that case the most likely address is returned and marked unconfirmed. It costs 0.25 credits when nothing is found. Nothing is charged for invalid input, for a domain that does not exist or cannot receive email, or when the check cannot be finished right now (status retry_later). Credits are the account's shared credits. Before calling, tell the user how many people there are, the price for each result and the most it can cost (the number of people times the found price). Ask the user to approve a spending limit and pass it as max_credits. The list never spends more than max_credits. It pauses with paused_reason=spend_limit and can be resumed with a higher limit through argorant_manage_find_emails. It also pauses when the account runs out of credits (insufficient_credits, resume after adding credits), at the daily lookup limit (it continues after midnight UTC), or when most lookups find nothing (it slows down and continues by itself). Duplicate people are removed, and rows without a usable name or domain are skipped for free (invalid_rows). Each address is checked live. The result has job_id, status, totals and maximum_charge right away. Call argorant_find_emails_status about every 30 seconds for progress and results. The results are also in the Argorant app (app_url) as a table and a CSV download. More in the docs at https://docs.argorant.com/docs/agents/tools#find-work-emails ### argorant_find_emails_status Check an email-finding list. Show a list started with argorant_find_emails. It shows the status (queued, running, paused, done or cancelled), how many people are done and how many are waiting, the count for each result, the credits charged so far, the spending limit and, when the list is paused, why. With include_results=true it also returns up to 200 result rows per call (row, ref, name, domain, email, status, confirmed, confidence, credits_charged). Use offset to see more. Rows still waiting show status pending. Rows held because the account ran out of credits show status unpaid and no email until the list is resumed. It does not start lookups or spend credits. The status is valid when the email was found and confirmed, so it is safe to use. It is catch_all when the company's domain accepts every address. That address is the best guess but unconfirmed, and it may bounce. The other statuses are not_found, no_mail_domain and retry_later. Tell the user which addresses are unconfirmed. More in the docs at https://docs.argorant.com/docs/agents/tools#find-work-emails ### argorant_get_campaign Get one campaign. Show one campaign with its emails, subsequences, sending mailboxes, numbers and anything that still stops a launch. copy_warnings lists text in the emails that would go out exactly as written, such as [link], [Name] or TBD, or a variable that some contacts do not have. variable_coverage shows, for each variable the emails use, how many contacts have no value for it. Those contacts wait at that email and are never sent a blank. Tell the user these numbers before a launch. Each email lists its variants, the other versions of that email, in the same shape argorant_set_campaign_emails takes. A version with enabled false is kept but no longer sent. It only reads and changes nothing. More in the docs at https://docs.argorant.com/docs/agents/tools#campaigns ### argorant_inbox Read replies across campaigns. Show replies, bounces and unsubscribes from every campaign in one place, newest first. folder can be all, replies, interested, not_interested, out_of_office, bounces or unsubscribes. You can also filter by campaign_id, by classification or by search text in q. Each row shows the start of the message. Open one in full with argorant_inbox_thread. More in the docs at https://docs.argorant.com/docs/agents/tools#inbox ### argorant_inbox_classify Change the label on a reply. Set the label on a conversation. The key must come from argorant_reply_statuses. In a customer workspace that is positive (shown as Interested), meeting_request, out_of_office, unsubscribe, neutral (shown as Other), any extra label that is switched on, or one of the workspace's own labels. More in the docs at https://docs.argorant.com/docs/agents/tools#inbox ### argorant_inbox_forward Forward a reply to someone. Forward a conversation from the mailbox that received it to up to ten addresses, such as a colleague, the user or a partner. The earlier messages and attachments are included, and you can add a note on top. It goes out at once as a real email, so only forward when the user asked for it. The result first shows delivery "checking". For three minutes Argorant watches for a rejection. Open the conversation with argorant_inbox_thread to see "delivered", or "rejected" with the reason. More in the docs at https://docs.argorant.com/docs/agents/tools#inbox ### argorant_inbox_order_status Check inbox orders. Show the workspace's inbox orders, or one order when you pass order_id. Each order shows its status and step (awaiting_payment, setting_up, aging, ready or attention), whether it was ordered through the API or by an assistant, and whether it was paid with the saved card or a link. It lists each domain with its expiry date, yearly renewal price and renewal_action (Stop renewal or Turn renewal back on), how many of the mailboxes are created, when aging ends, and the billing bundles with their bundle_id and the cancel reasons for argorant_cancel_inbox_bundle. New mailboxes wait 24 hours after setup before they send. It only reads and changes nothing. More in the docs at https://docs.argorant.com/docs/agents/tools#new-inboxes ### argorant_inbox_reply Answer a reply. Send a plain-text answer in the same thread, from the mailbox that received the reply. It goes out at once as a real email. Show the user the text and get their yes first. More in the docs at https://docs.argorant.com/docs/agents/tools#inbox ### argorant_inbox_thread Open one conversation. Show one conversation from argorant_inbox in full, oldest message first. It includes the campaign's emails, the replies, the answers sent and any forwards, with who wrote each one, the campaign and the mailbox. Each forward shows whether it is still being checked, was delivered, or was rejected, with the reason it was rejected. More in the docs at https://docs.argorant.com/docs/agents/tools#inbox ### argorant_integration_push_status Check a send to a connected tool. How a send to a connected sending tool stands: waiting for its export, sending, done or failed, with how many people were sent, were already in that campaign, or were not accepted there. It is free, only reads and changes nothing. More in the docs at https://docs.argorant.com/docs/agents/tools#send-to-other-tools and https://docs.argorant.com/docs/guides/send-to-other-tools ### argorant_launch_campaign Launch, pause or stop a campaign. Launch, pause or stop a campaign. action=launch starts sending real emails to real people from the campaign's mailboxes, so ask the user for a clear yes first. action=pause holds the campaign. action=stop ends it for good. A launch is refused while the campaign has no email, no sending mailbox or no people, or while an email still has text that would go out exactly as written, such as [link], [Name] or TBD, or while a variable has no value for any contact. The error names each problem. The answer also says how many contacts wait because a value is missing; tell the user. Fix the text with argorant_set_campaign_emails. Only when the user clearly says that text is meant to be sent, launch again with allow_placeholders=true. More in the docs at https://docs.argorant.com/docs/agents/tools#campaigns ### argorant_list_campaign_leads List the people in a campaign. List the people in a campaign with their status (queued, active, replied, bounced, completed, suppressed or pending) and email_grade (valid, catch_all, checking and others). Filter by status or by search text, and page through with limit and offset. status=held shows the contacts waiting at an email because a variable it uses has no value for them, each with the reason. It only reads and changes nothing. More in the docs at https://docs.argorant.com/docs/agents/tools#campaigns ### argorant_list_campaigns List your email campaigns. List every campaign in the account with its status, people, emails sent, replies and sending mailboxes. It only reads and changes nothing. More in the docs at https://docs.argorant.com/docs/agents/tools#campaigns ### argorant_list_inboxes List connected mailboxes. List the Google and Microsoft mailboxes connected to the account, with their health and daily sending limits. It only reads, changes nothing and shows no passwords. More in the docs at https://docs.argorant.com/docs/agents/tools#mailboxes ### argorant_list_integrations List connected sending tools. Show the tools the user connected in Argorant under Settings, Integrations, each with its id and whether it can receive people directly (can_receive_people). Give integration_id to also list the campaigns inside that tool, so the user can pick where people go. A tool is connected only in the Argorant app with that tool's own API key: never ask the user for such a key here. It is free, only reads and changes nothing. More in the docs at https://docs.argorant.com/docs/agents/tools#send-to-other-tools and https://docs.argorant.com/docs/guides/send-to-other-tools ### argorant_list_lists List saved lists. Show every saved list and saved search in the user's account, newest first, with its id, its name, how many people it holds and when it changed. Use the id with argorant_list_status, argorant_export_list, argorant_add_campaign_leads or argorant_rename_list. Set kind to lists for people the user picked, to saved_searches for searches that stay up to date, or leave it at all. A page holds up to 100. When has_more is true, call again with next_cursor. It is free, only reads and changes nothing. More in the docs at https://docs.argorant.com/docs/agents/tools#lists ### argorant_list_status Check a saved list. Show the details of a saved lead list, the search it was saved from and a few of its record IDs, and whether it is still being filled. A saved search and every add to a list are filled in the background, one after the other; filling says whether that is still going on and summary says it in a sentence. Add a list to a campaign or export it once it is ready. It is free, starts no export and shows no contact details. More in the docs at https://docs.argorant.com/docs/agents/tools#lists ### argorant_manage_find_emails Resume or cancel an email-finding list. Resume or cancel a paused list. When resuming, you can pass a new spending limit the user approved as max_credits. Resuming continues the lookups and spends credits at the same prices. Each person costs 1 credit when an email is found and confirmed, and 1 credit when the company's domain accepts every address (catch-all). In that case the most likely address is returned and marked unconfirmed. It costs 0.25 credits when nothing is found. Nothing is charged for invalid input, for a domain that does not exist or cannot receive email, or when the check cannot be finished right now (status retry_later). Credits are the account's shared credits. People already done are never charged again. Rows held for missing credits are paid first, without a new lookup. Cancelling stops the list. People not done yet are never looked up or charged, and charges already made stay. Only resume after the user agreed to continue. More in the docs at https://docs.argorant.com/docs/agents/tools#find-work-emails ### argorant_order_inboxes Order the quoted inboxes. Order exactly one quote from argorant_quote_inboxes. Show the user the full quote (every domain with its first-year and renewal price, the mailboxes, due today, the recurring total, the currency rule, what is included and how it is paid) and order only after their explicit yes. Set confirmed=true only with that yes. Through Claude or ChatGPT, this always returns checkout_url, a payment link the user opens and pays themselves, and a saved card is never charged; only the workspace owner gets that link. Through an API key or another app, when the quote said the saved card is usable, this call charges that card right away (the amount due today, within the limits the workspace set), so tell the user which card and how much before they say yes. Otherwise, or when the card cannot be charged, it returns checkout_url, which is a payment link the user pays themselves. Tell the user the reason given in saved_card.reason. You never enter card details, open, complete or pay a payment page. Nothing is bought before the payment went through, and setup starts after it. argorant_inbox_order_status shows each step. Never retry with a new quote to get around a limit or a refusal. pay_with=link always returns a payment link. sender_names are the people the mailboxes send as, from 1 up to as many as there are domains. Each must be a real first and last name in Latin letters, because it becomes the email address. website is where visitors of the new domains are sent, and it is optional. Anyone in the workspace can buy with the saved card when the quote says so. Only the workspace owner gets a payment link. Sending the same call again returns the same order and never charges twice. More in the docs at https://docs.argorant.com/docs/agents/tools#new-inboxes ### argorant_preview_people Preview matching people. Show example people who match a search, with their names hidden. Each row shows initials, job, company, place and department. company_normalized is the short company name people say. Use keywords for words that describe what the company does, such as MSP or freight forwarding; a comma means any of them. Use industry for broad sectors. Plain words such as logistics, healthcare or law firms are matched to Argorant's industries, and other words are matched as keywords. The result's industry_note says how the word was read. Every list filter has a matching exclude filter, such as exclude_title, exclude_keywords, exclude_industry, exclude_country, exclude_seniority, exclude_departments or exclude_company_domain. Include and exclude work together, and a comma means any of them. Keywords look at what the company does, that is its name, tags, industry and description. Set them to look at people's own skills only when the user wants people who have a skill themselves, such as people who know Python, or at both. Job titles match whole words unless you choose exact roles or contains with title_match. Employee and revenue ranges work the same way everywhere. It costs no credits. It counts toward a daily limit, which is a safety limit and costs nothing. It shows no email addresses, phone numbers or profile links. To get those, use argorant_reveal_people. To find companies by who they sell to, set company_category and sells_to, or write it in q, for example "software companies selling to restaurants". That returns the companies that sell, never their customers. More in the docs at https://docs.argorant.com/docs/agents/tools#read-and-preview ### argorant_push_to_integration Send people to a connected sending tool. Send the people of one of the user's Argorant campaigns (source campaign, with campaign_id) or the rows of one of their exports (source export, with export_id) into a campaign in a connected sending tool (target_campaign_id from argorant_list_integrations). People who bounced, unsubscribed or are blocked are never sent. To send a saved list, export it first with argorant_export_list (that export uses credits as usual, so get the user's yes for it) and send that export: the send waits until the export is ready. The campaign in the other tool is not started and no email is sent. It is free from the Pro plan. Tell the user which campaign or export goes where and how many people that is, and send only after their explicit yes (confirmed=true). Then report the result with argorant_integration_push_status. More in the docs at https://docs.argorant.com/docs/agents/tools#send-to-other-tools and https://docs.argorant.com/docs/guides/send-to-other-tools ### argorant_quote_credits Quote a credit pack. Get a price for one credit pack (credits must be one of the pack sizes from argorant_credit_packs) and see how it would be paid. Through Claude or ChatGPT, buying always returns a payment link the user opens and pays themselves, and a saved card is never charged. Through an API key or another app, when payment.saved_card.usable is true, buying charges that saved card right away, within the monthly limit the account owner allowed in the app. Otherwise buying returns a payment link, and payment.saved_card.reason says why. The result has quote_id. Nothing is bought or charged by this call. Show the user the pack, the price and the currency, and how it will be paid, and buy only after their explicit yes. More in the docs at https://docs.argorant.com/docs/agents/tools#credits ### argorant_quote_inboxes Quote new sending inboxes. Get a price for new mailboxes on their own new domains, for cold email. Give mailboxes (how many) or daily_volume (cold emails a day, where each mailbox sends 5 a day). Add domains (exact names), company (a website or brand to pick available names from), or both. The endings on offer are .com, .net, .org, .co, .sbs, .biz, .info. Mailboxes come in bundles of 100 on 2 domains. The result has quote_id (valid for 24 hours), every domain with whether it is available and its first-year and renewal price, the mailbox price, due_today_cents, recurring_cents (per month or quarter), renewal_per_year_cents, the currency rule, what is included and how it would be paid. Through Claude or ChatGPT, the order always returns a payment link the user opens and pays, and a saved card is never charged. Through an API key or another app, when payment.saved_card.usable is true, the order is charged right away to that saved card, and the user has to confirm within 15 minutes of the quote. Otherwise the order returns a payment link. Nothing is ordered or charged by this call. Show the user the full quote (every domain with its first-year and renewal price, the mailboxes, due today, the recurring total, the currency rule, what is included and how it is paid) and order only after their explicit yes. Warm-up is not part of a mailbox order: never offer, sell or price it, and a plan is not needed to buy mailboxes. More in the docs at https://docs.argorant.com/docs/agents/tools#new-inboxes ### argorant_quote_verification Price a check of your email list. Get a price for checking email addresses the user already has. This is separate from searching for people in Argorant. It takes up to 1,000 different addresses (5,000 rows). Duplicates are removed, and the row numbers of entries that are not email addresses are listed. The quote is kept privately for 15 minutes. It checks nothing and spends no credits. Each new check costs half a credit, so two checks cost 1 credit, rounded up for each run. Addresses checked recently are free to check again. Any older check balance on the account is used before credits. The result shows the counts, the most it can cost in credits and the credits left, without repeating the addresses. Show these to the user and ask the user before starting the check. More in the docs at https://docs.argorant.com/docs/agents/tools#verify-your-own-list ### argorant_remove_campaign_lead Remove one person from a campaign. Take one email address out of the campaign. Nothing more is sent to that person from this campaign. More in the docs at https://docs.argorant.com/docs/agents/tools#campaigns ### argorant_remove_campaign_sender Remove a mailbox from a campaign. Take one sending mailbox off the campaign. The mailbox stays connected to the account. More in the docs at https://docs.argorant.com/docs/agents/tools#campaigns ### argorant_rename_list Rename a saved list. Give a saved list or saved search a new name. Its people and its id stay the same. It is free. Tell the user the new name. More in the docs at https://docs.argorant.com/docs/agents/tools#lists ### argorant_reply_statuses List reply labels. List the labels you can give replies in the Unibox. A customer workspace has five standard labels, positive (shown as Interested), meeting_request, out_of_office, unsubscribe and neutral (shown as Other). It can switch on extra labels (not_interested, question, referral, wrong_person, meeting_booked) and add its own, each with a short description. Each label says whether it is visible. Use the key with argorant_inbox_classify. More in the docs at https://docs.argorant.com/docs/agents/tools#inbox ### argorant_reveal_people Reveal contact details. Show the full contact details of a small group of people who match a search: name, job, company, work email and profile link. Only working email addresses are shown and charged. Each person whose email is new to this account costs 1 credit. People this account already unlocked are free, in the app, the API and here. Ask the user before you spend credits. Phone numbers are only included when include_phones is true. They cost 10 credits per phone number returned, nothing if none is found. Ask the user before spending. The result's summary says what was shown and what it cost. Tell the user. A daily limit caps how many people can be revealed. It is a safety limit and costs nothing. To find companies by who they sell to, set company_category and sells_to, or write it in q, for example "software companies selling to restaurants". That returns the companies that sell, never their customers. Every list filter has a matching exclude filter, such as exclude_title, exclude_keywords, exclude_industry, exclude_country, exclude_seniority, exclude_departments or exclude_company_domain. Include and exclude work together, and a comma means any of them. Keywords look at what the company does, that is its name, tags, industry and description. Set them to look at people's own skills only when the user wants people who have a skill themselves, such as people who know Python, or at both. Job titles match whole words unless you choose exact roles or contains with title_match. Employee and revenue ranges work the same way everywhere. More in the docs at https://docs.argorant.com/docs/agents/tools#reveal-enrich-export ### argorant_set_campaign_emails Write the campaign emails. Replace the campaign's emails. The first email opens the conversation and needs a subject. Each later email is a follow-up, sent delay_days after the one before. You can use {{first_name}}, {{last_name}}, {{company}}, {{company_normalized}} and {{title}} in the text. {{company_normalized}} is the name people say (Tidal, not Tidal Brand-Led Performance Marketing Agency), so prefer it in the body. If a contact has no value for a variable, that contact waits at that email instead of getting a blank. To send them anyway, add a fallback after a | sign inside the double braces, for example {{company_normalized|your team}}, which writes "your team" when the name is missing. Spintax is something else. It uses single braces such as {Hi|Hello} and picks one at random for every email. {{sender_first_name}} is the first word of the sending mailbox's display name, so a sign-off with it matches every mailbox in the rotation. {{sender_name}} is the full display name. A contact whose mailbox has no display name waits at that email. Set the name with argorant_update_inbox, or give it a fallback such as {{sender_first_name|Sam}}, written with the name the user wants there. Each email can also carry variants, a list of up to 9 other versions for an A/B test. Each version needs a body and can have its own subject and a label. Without a subject it uses the email's subject. Each contact gets one version of every email, picked at random with equal odds, so the main text and each variant reach about the same share of contacts. The label names the version in the results, such as "angle cost". argorant_campaign_analytics shows the results per version. Saving replaces the variants of every email, so send all of them again when you change one. For a personal line per contact, use the campaign's own {{custom_...}} variables, written in lowercase exactly as defined with argorant_set_campaign_personalization. Each contact gets the line written for them, or the variable's fallback. Any other {{custom_...}} name is flagged. To write those lines, follow the personalization playbook, which argorant_set_campaign_personalization returns. Follow-ups go in the same thread by default, with "Re:" before the subject. Write the final text and never leave placeholders such as [link], [Name], , {link}, TBD or XX. If a link or detail is unknown, ask the user or leave it out. The result's warnings list anything that would still go out exactly as written, each with its email and text, and its summary says the same in one sentence. Fix every warning with another call before anyone launches. A launch is held while one remains. Set allow_placeholders=true only when the user clearly wants that text sent as written. A running campaign refuses the save otherwise. More in the docs at https://docs.argorant.com/docs/agents/tools#campaigns ### argorant_set_campaign_personalization Define per-contact lines for a campaign. Set up the campaign's personal lines, one per contact. Define 1 to 5 {{custom_...}} variables. Each has one instruction (what the line says, how long it is and its style, with examples) and one fallback (a line that reads well for anyone). This replaces the campaign's earlier setup. Every contact without their own line gets the fallback at once, so the emails can use the variables and the campaign can launch at any time. template is optional and holds the email text the line goes into. extra_columns names contact or company fields worth reading, such as industry, city or title. allow_links=false keeps links out of the lines, which is recommended. The result is plain data with the saved variables and their fallbacks, how many contacts have the fallback now, and playbook, the written method for writing the lines, as plain data. Next, look up facts for each contact and never invent anything. Then show the user 5 example lines first, and after their yes write all of them with argorant_set_lead_custom_fields. More in the docs at https://docs.argorant.com/docs/agents/tools#campaigns ### argorant_set_campaign_senders Choose the mailboxes that send. Choose which connected mailboxes send this campaign, by email address, or use all of them with all_connected=true. argorant_list_inboxes shows what is connected. More in the docs at https://docs.argorant.com/docs/agents/tools#campaigns ### argorant_set_campaign_subsequences Write the campaign subsequences. Replace the campaign's subsequences. A subsequence is a set of follow-up emails that starts when a reply contains a keyword. You can have up to 5. Each has a name, keywords (1 to 10 words or short phrases) and emails (1 to 8, in the same shape as for argorant_set_campaign_emails, with subject?, body, delay_days?, same_thread? and variants?). A keyword also counts in capitals, as a plural, with a small typo or inside a short sentence: 'interested' matches 'Interested!', 'intrested' and 'very interested', but never 'interesting'. When a reply matches, that person leaves the main emails and gets the first matching subsequence in the same thread. The order of the list decides which one comes first. Its first email goes out delay_days after the reply, where 0 means the next sending window, and its subject is 'Re: {{thread_subject}}' unless you set one. Quoted text in a reply is ignored. A keyword after 'not' or 'no' ('not interested', 'no meeting') never counts, and replies asking to stop never start one. An empty list removes them all. argorant_get_campaign shows the current ones. More in the docs at https://docs.argorant.com/docs/agents/tools#campaigns ### argorant_set_inbox_domain_renewal Stop or turn back on a domain's renewal. Stop renewal (on=false) or Turn renewal back on (on=true) for one ordered domain. Nothing is charged now either way. A stopped domain keeps working until its expiry date and is then not renewed. Domains are never deleted early. A domain with renewal on renews at its expiry date at its yearly renewal price, billed shortly before. Tell the user the message in the result, which names the date and the price. Ask the user for explicit approval first. Only the workspace owner can change it. More in the docs at https://docs.argorant.com/docs/agents/tools#new-inboxes ### argorant_set_lead_custom_fields Write each contact's personal line. Save the personal lines you wrote, for up to 200 contacts per call, as [{lead_id or email, values: {custom_...: "line"}, basis}]. For a contact you checked who has no usable facts, send {lead_id or email, keep_fallback: true}. Only the campaign's own variables from argorant_set_campaign_personalization are accepted. Write each line only from facts you actually looked up for that contact, and never invent a detail, a number, a customer or a claim. Good sources are the facts in argorant_campaign_personalization_status, the company's website and argorant_company_people. When the facts do not tell you, send keep_fallback: true for that contact. It keeps the fallback and leaves the list. basis says in a few words where the fact came from. Before the first save, show the user 5 example lines inside their sentences and wait for a yes. Each line is plain text on one line, within the variable's length, with no links unless the campaign allows them. Saved contacts are marked as personalized, and Argorant never overwrites them. The result lists the lines it refused with the reason (fix those and send them again), contacts not in the campaign, and the progress. For more than a few hundred contacts, write the ones sent first and continue later. Everyone else sends with the fallback. More in the docs at https://docs.argorant.com/docs/agents/tools#campaigns ### argorant_start_verification Start the email list check. Check the email list from a quote made with argorant_quote_verification in the last 15 minutes. Ask the user to approve the most it can cost first, and pass that number of credits as approved_maximum_charge. Each new check costs half a credit, and any older check balance is used first. Addresses checked recently are free. The user does not need to buy any contacts for this. Argorant never charges more than the quote or the approved amount, whichever is smaller. Sending the same quote again continues the same check and does not charge twice. The result has the status and a link to the results in Argorant, not the email addresses. Follow the progress with argorant_verification_status. If an answer from this tool is unclear, check there and never start a new quote on your own. More in the docs at https://docs.argorant.com/docs/agents/tools#verify-your-own-list ### argorant_suggest_inbox_domains Suggest domain names for new inboxes. Suggest available domain names for new sending mailboxes, based on the user's company website (company, for example acme.com; a brand name alone is not enough, ask the user for their website). Each name comes with its first-year price and its yearly renewal price, in cents, for each currency. The endings on offer are .com, .net, .org, .co, .sbs, .biz, .info, and the result's endings field has the current list. Use ending to get names with only one of them. Use this when the user wants other names than the ones the quote picked. It only checks which names are available. Nothing is reserved, ordered or charged. More in the docs at https://docs.argorant.com/docs/agents/tools#new-inboxes ### argorant_test_smtp_mailbox Test a mailbox sign-in. Check that Argorant can sign in to a mailbox from any email provider, such as Zoho, Fastmail, Yahoo, iCloud, IONOS or your web host, before connecting it. It tries sending and reading replies and says for each one whether it works, or what is wrong in plain words, for example a wrong password, a server that does not answer, or a security setting that does not match. Nothing is saved and no email is sent. Many providers need an app password instead of the normal one. Google and Microsoft mailboxes connect with their own sign-in instead (argorant_connect_google_workspace, or the Mailboxes page in Argorant). It is free. Through Claude, never ask for a mailbox password: this returns connect_url, the link to Argorant's own mailbox form, where the user enters it and the sign-in is tested. More in the docs at https://docs.argorant.com/docs/agents/tools#mailboxes ### argorant_test_webhook Send a test event to a webhook. Send one test event to a webhook (its id comes from argorant_webhooks) so the user can see it arrive. It is marked as a test and changes nothing in the account. It is free. More in the docs at https://docs.argorant.com/docs/agents/tools#webhooks and https://docs.argorant.com/docs/guides/webhooks ### argorant_unblock Remove an address or domain from the blocklist. Take one entry off the workspace's blocklist, so campaigns may contact that address or domain again. Use the id from argorant_blocklist. People who were stopped by the entry are not added back on their own. Ask the user for explicit approval first. It is free. More in the docs at https://docs.argorant.com/docs/agents/tools#analytics-mailbox-settings-blocklist ### argorant_update_campaign Change campaign settings. Change any campaign setting. Only the fields you pass change. You can set name, daily_limit (for the whole campaign per day), per_mailbox_daily_limit, max_active_mailboxes, timezone (a name such as America/New_York), timezone_mode ('fixed', or 'lead' for each person's local time), window_start and window_end (such as '08:00' and '17:00'), skip_weekends, gap_minutes_min and gap_minutes_max, include_unsubscribe, planned_start_date (YYYY-MM-DD) and tags. stop_on_reply is true by default, so a reply ends that person's emails. With false the emails keep going unless the reply starts a subsequence or asks to stop. Bounce protection is on for new campaigns. auto_pause=true pauses the campaign by itself when too many emails bounce or its mailboxes go offline, and only a person can start it again. auto_pause_bounce_rate_pct is the bounce rate that pauses it (1 to 50, default 10). auto_pause_min_sent is how many people must be contacted before that rule applies (default 100). auto_pause_when_offline is true by default. auto_pause_offline_share_pct is the share of mailboxes offline that pauses it (default 100, which means all of them). Campaigns always send plain text. More in the docs at https://docs.argorant.com/docs/agents/tools#campaigns ### argorant_update_inbox Change mailbox settings. Change a connected mailbox's daily limit, turn warm-up on or off, make it active or not, or change its display name or timezone. Only the fields you pass change. More in the docs at https://docs.argorant.com/docs/agents/tools#analytics-mailbox-settings-blocklist ### argorant_update_reply_status Change a reply label. Change one reply label (its key comes from argorant_reply_statuses). The workspace's own labels can get a new name, colour or description, and the key stays the same. Standard and optional labels can only be hidden (visible=false) or shown again. The colour is one of lime, blue, purple, yellow, rose or neutral. Only the fields you pass change. It is free. More in the docs at https://docs.argorant.com/docs/agents/tools#inbox ### argorant_verification_status Check your verification results. Show how far a check of the user's email list has come, how many addresses got each result and what it actually cost. Returns a link to the full results and a CSV file in Argorant, for the signed-in user. It starts no checks, buys no contacts and spends no credits. Only valid means an address was confirmed to work. Unknown, risky and catch-all do not mean that. More in the docs at https://docs.argorant.com/docs/agents/tools#verify-your-own-list ### argorant_webhooks List webhooks. Show the web addresses Argorant notifies when something happens, such as a reply, a positive reply, a bounce, an export or a list check that is ready, or a paused campaign. Each one comes with the events it receives, and the result also lists every event the user can pick. It is free, only reads and changes nothing. More in the docs at https://docs.argorant.com/docs/agents/tools#webhooks and https://docs.argorant.com/docs/guides/webhooks ### fetch Open a search result. Open a result from search. It shows how many people match and up to five example rows with job and company, names hidden. It shows no contact details and costs no credits. Each fetch counts as one count and one preview toward the daily limits, which are safety limits and cost nothing. More in the docs at https://docs.argorant.com/docs/agents/tools#read-and-preview ### search Quick search by company or words. Count how many people Argorant has for a company domain or a few simple words. If the text contains a domain, only the domain is used and the other words are ignored. For a search that combines job, place and company, use argorant_count_people or argorant_preview_people instead. Returns the count and two results to open with fetch. It shows no contact details. It costs no credits. It counts toward a daily limit, which is a safety limit and costs nothing. More in the docs at https://docs.argorant.com/docs/agents/tools#read-and-preview # Argorant Developer Hub URL: https://docs.argorant.com/docs A complete B2B outreach platform your code or your AI agent can run from start to finish. Find people, get checked emails and phone numbers, run campaigns and answer replies. Argorant does the whole outreach job in one place, and every step is an API call. Find the companies and people that fit your offer among 626.5M+ contacts in 202 countries. Get their work emails, checked right before you receive them, and their phone numbers. Find one person's email from a name and a company domain. Check the emails on lists you already have. Write a campaign with a personal line for every contact, send it from your own Google Workspace or Microsoft 365 mailboxes or from new mailboxes we set up on new domains for you, and answer the replies in the same thread. You can do all of it from code, from the terminal, or by asking an AI agent such as Claude, ChatGPT or Codex. The REST API, the command line tool `npx argorant` and the MCP server `https://mcp.argorant.com/mcp` share one account, one credit balance and the same rules. ## What it costs [#what-it-costs] Argorant is the cheapest way to get validated B2B contacts. With pay as you go, 100,000 credits cost $499, which is under half a cent per validated contact. On Hyperscale, 200,000 credits a month cost $649, about a third of a cent each. An email that fails the check costs nothing. Compare the prices yourself on [our comparison pages](https://argorant.com/compare) and the [alternatives](https://argorant.com/alternatives), for example Argorant and [ZoomInfo](https://argorant.com/compare/zoominfo-vs-argorant), [Cognism](https://argorant.com/compare/cognism-vs-argorant), [Hunter](https://argorant.com/compare/hunter-vs-argorant), [LeadIQ](https://argorant.com/compare/leadiq-vs-argorant), [Prospeo](https://argorant.com/compare/prospeo-vs-argorant), [Seamless](https://argorant.com/compare/seamless-vs-argorant) or [UpLead](https://argorant.com/compare/uplead-vs-argorant) side by side. | What you do | Price | | ----------------------------------------------------- | ------------------------------------------------------------------- | | Count, search, preview, look up industries and titles | Free | | Get a contact with a checked work email | 1 credit. Emails that fail the check are left out and cost nothing. | | Get a phone number | 10 credits, only when one is returned (from the Pro plan) | | Find one email from a name and a domain | 1 credit when found, 0.25 when nothing is found | | Check an email from your own list | 0.5 credit. Addresses checked recently are free. | | Send campaign emails | Included in your plan, never credits | Pay as you go from $17.50 for 500 credits to $499 for 100,000 credits, valid for a year. Plans start at $99 a month for 5,000 credits and 100,000 campaign emails. New accounts get a 14-day trial with 100 credits and 300 campaign emails, without a card. All prices are on [argorant.com/pricing](https://argorant.com/pricing). ## What one job looks like [#what-one-job-looks-like] | Step | REST | Command line | MCP tool | | --------------------------- | ---------------------------------------------------- | ------------------------------------------ | ----------------------------------------------------------- | | Size the market, free | `GET /api/v1/people/count` | `argorant count` | `argorant_count_people` | | Look at who matches, free | `GET /api/v1/people/search` | `argorant search` | `argorant_preview_people` | | Save them as a list | `POST /api/v1/lists` | `argorant list create` | `argorant_create_list` | | Create a campaign | `POST /api/v1/campaigns` | `argorant campaigns create` | `argorant_create_campaign` | | Write the emails | `POST /api/v1/campaigns/{id}/emails` | `argorant campaigns emails set` | `argorant_set_campaign_emails` | | Add the list | `POST /api/v1/campaigns/{id}/leads` | `argorant campaigns leads add` | `argorant_add_campaign_leads` | | Choose mailboxes and launch | `POST .../senders`, `POST .../launch` | `argorant campaigns senders set`, `launch` | `argorant_set_campaign_senders`, `argorant_launch_campaign` | | Read and answer replies | `GET /api/v1/inbox`, `POST /api/v1/inbox/{id}/reply` | `argorant inbox list`, `reply` | `argorant_inbox`, `argorant_inbox_reply` | Every operation says what it costs and whether it spends credits, sends email or charges money, so an agent can ask the user before it does anything that matters. # ChatGPT URL: https://docs.argorant.com/docs/agents/chatgpt Add Argorant to ChatGPT as a custom connection. Developer mode must be on first; personal and business accounts differ in who may switch it on. You need an Argorant account and a ChatGPT account where **Developer mode** is available. No Argorant account yet? The sign-in step offers **Create account**, with a 14-day trial, 100 credits and 300 campaign emails, without a card. On a personal Plus or Pro account you switch it on yourself; on Team, Enterprise or Edu an **owner or admin** must allow it in workspace settings before you see it. ### Turn on developer mode [#turn-on-developer-mode] Open **Settings → Security and login → Developer mode** (ChatGPT web). If the switch is missing, your workspace policy hides it; ask an admin to enable *Developer mode* for the workspace, or use a personal account for the setup. ### Create the connection [#create-the-connection] Open **Settings → Connectors** (or **Plugins**) and press **+ Create**. | Field | Value | | ------------------------------------------------------------------- | ------------------------------------ | | Name | `Argorant` | | Description | `Find and reach your next customers` | | MCP server URL | `https://mcp.argorant.com/mcp` | | Authentication | **OAuth** | | Save. ChatGPT reads the connector manifest and shows the tool list. | | ### Sign in [#sign-in] Press **Connect** and approve the Argorant consent screen with your Argorant account. The grant is per ChatGPT account and can be revoked from Argorant at any time. ### Use it in a chat [#use-it-in-a-chat] Start a new chat, open **+ → Developer mode** (or **More → Connectors**), tick **Argorant**, and ask: *"Check my Argorant account."* Then: *"How many CFOs at software companies in Germany can we reach?"* Counts and previews are free. ## Deep research [#deep-research] Argorant exposes `search` and `fetch`, the two tools ChatGPT's research modes look for. Coverage questions ("what do you have at stripe.com?") work there; reveals, exports and campaigns need the full connection in a normal chat. ## Directory listing [#directory-listing] A reviewed Argorant app in the ChatGPT directory is a separate release. The steps above work today through developer mode and are the same connection the listing will use. # Claude Code URL: https://docs.argorant.com/docs/agents/claude-code Connect Claude Code to Argorant with one command, for you or for a whole project, and let it prospect, verify and run campaigns from the terminal. You need Claude Code and an Argorant account. No account yet? The sign-in that opens on the first tool call offers **Create account**, with a 14-day trial, 100 credits and 300 campaign emails, without a card. ### Add the server [#add-the-server] For yourself, in every project: ```bash claude mcp add --transport http --scope user argorant https://mcp.argorant.com/mcp ``` For one project, so teammates get it too, put this in `.mcp.json` at the project root: ```json { "mcpServers": { "argorant": { "type": "http", "url": "https://mcp.argorant.com/mcp" } } } ``` ### Sign in [#sign-in] Run `/mcp` inside Claude Code, pick **argorant** and choose **Authenticate**. The browser opens the Argorant sign-in; approve the scopes. Claude Code stores the OAuth token, never an API key. Without this step the first tool call triggers the same prompt. ### Check the connection [#check-the-connection] ```text > Check my Argorant account. ``` You should see the connected email, your plan, your credits and what is left of today's limits. `claude mcp list` shows the server as connected. ## Try it [#try-it] * *"Find the person responsible for partnerships at Acme and their verified business email address."* * *"Find 500 relevant business owners for my bookkeeping business, draft an introduction and two follow-ups, and prepare the campaign using my connected inboxes. Show me the audience and messages before sending."* * *"Check the email addresses in `leads.csv` and separate valid from invalid before I use it."* ## Or use the CLI [#or-use-the-cli] Claude Code is good at terminals. `npx argorant … --json` returns machine-readable output and exit codes it can branch on, and it needs no MCP setup at all; see [CLI](/docs/guides/cli). Both routes use the same account, lists and credits. ## What to expect [#what-to-expect] * Counts, previews and reading your account run without asking. Anything that spends credits (reveal, export, enrich) or sends email (launch, reply) is marked destructive; Claude Code asks before it calls. * If a tool answers `scope_missing`, run `/mcp` and authenticate again; the scope list is on [Security and scopes](/docs/agents/security). # Claude URL: https://docs.argorant.com/docs/agents/claude Add Argorant to Claude.ai and Claude Desktop as a custom connector. One URL, one sign-in, then ask Claude to size a market or run a campaign. You need an Argorant account and a Claude account. No account yet? The sign-in step offers **Create account**, with a 14-day trial, 100 credits and 300 campaign emails, without a card. On Team and Enterprise plans an **owner or admin** adds the connector for the organisation first; members then enable it for themselves. ### Open Connectors [#open-connectors] In Claude, open your profile menu, then **Settings → Connectors** (`https://claude.ai/settings/connectors`). Claude Desktop shares the same settings. ### Add a custom connector [#add-a-custom-connector] Scroll to the bottom and choose **Add custom connector**. Call it `Argorant` and paste this as the remote MCP server URL: ```text https://mcp.argorant.com/mcp ``` Leave the advanced OAuth fields empty; Argorant registers the client itself. ### Sign in [#sign-in] Claude opens the Argorant sign-in. Sign in, or create your account right there, and approve the scopes. The connector never sees an API key; the grant can be revoked at any time. ### Enable it in a chat [#enable-it-in-a-chat] In a conversation open the **+** (or the tools) menu, turn on **Argorant** under Connectors, then ask: *"Check my Argorant account."* You should see the connected email, your plan, your credits and what is left of today's limits. ## Try it [#try-it] * *"I run a commercial cleaning business in London. Find 30 local businesses I could approach and the people responsible for choosing their cleaning provider, with verified work emails."* * *"Find 1,000 founders of UK software companies with 10 to 50 employees and save them to a prospect list."* * *"Draft an introduction and two follow-ups for that list, set up the campaign with my connected inboxes and show me everything before sending."* ## What to expect [#what-to-expect] * Counts, previews and reading your account run without asking. Anything that spends credits (reveal, export, enrich) or sends email (launch, reply) is marked destructive; Claude asks before it calls. * Claude keeps raw contact details out of the chat unless you ask for them. * If a tool answers `scope_missing`, reconnect the connector; the scope list is on [Security and scopes](/docs/agents/security). Working in the terminal? [Claude Code](/docs/agents/claude-code) connects with one command. # Codex URL: https://docs.argorant.com/docs/agents/codex Point Codex at the Argorant MCP server with one config block, or install the Argorant plugin that adds skills for the whole workflow. You need the Codex CLI or Codex in your editor, and an Argorant account. No account yet? The sign-in that opens on the first tool call offers **Create account**, with a 14-day trial, 100 credits and 300 campaign emails, without a card. ## Option A: the MCP server [#option-a-the-mcp-server] Add this to `~/.codex/config.toml`: ```toml [mcp_servers.argorant] url = "https://mcp.argorant.com/mcp" ``` Or from the terminal: ```bash codex mcp add argorant --url https://mcp.argorant.com/mcp ``` Restart Codex. The first Argorant tool call opens the browser for the Argorant sign-in; Codex stores the OAuth token, never an API key. ## Option B: the Argorant plugin [#option-b-the-argorant-plugin] The plugin carries the same MCP connection plus five skills that teach Codex the safe order of operations: * **Find sales contacts** turns a description of your customers into a checked audience and reveals only what you approve. * **Enrich a known contact** turns an email, or a name plus company domain, into the full record. * **Export a sales list** saves the people as a list, builds an export of the size you approve and hands over the file. * **Verify an email list** gets a quote, waits for your yes to the most it costs, and shows the results. * **Run an email campaign** checks the mailboxes, drafts the emails and shows them before saving, adds the people, picks the senders, clears what blocks the launch and launches only after your yes. Install it from the plugin directory once Argorant is listed, or from the package we ship on request. ## Option C: the CLI [#option-c-the-cli] Codex is good at terminals. `npx argorant … --json` returns machine-readable output and exit codes it can branch on; see [CLI](/docs/guides/cli). # Connect a client URL: https://docs.argorant.com/docs/agents/connect The canonical MCP setup for every client. One URL, one OAuth prompt, then start with counts. ## Endpoints [#endpoints] | What | URL | | ----------------------------- | ----------------------------------------------------------------- | | MCP server (streamable HTTP) | `https://mcp.argorant.com/mcp` | | Authorization server metadata | `https://mcp.argorant.com/.well-known/oauth-authorization-server` | | Protected resource metadata | `https://mcp.argorant.com/.well-known/oauth-protected-resource` | | Connector manifest | `https://mcp.argorant.com/manifest.json` | OAuth 2.1 authorization code with PKCE. Clients that cannot be pre-registered self-register at the registration endpoint (dynamic client registration). Refresh tokens are issued. ## No account yet [#no-account-yet] The sign-in page every client opens has a **Create account** link. Sign up there with an email and password or with Google, confirm the code we email you, and you land back on the consent screen. The agent is connected the moment you approve. New accounts start a 14-day trial with 100 credits and 300 campaign emails, without a card. Counts and previews never spend credits; reveals, exports and enrichment do. Campaigns need a connected Google Workspace or Microsoft 365 mailbox. ## Per client [#per-client] | Client | Where | Steps | | -------------- | ------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------ | | Claude | Settings → Connectors → Add custom connector | Paste the URL, sign in. Team and Enterprise: an owner adds it, members connect. [Guide](/docs/agents/claude) | | Claude Code | `claude mcp add --transport http argorant …` | Then `/mcp` → Authenticate. [Guide](/docs/agents/claude-code) | | ChatGPT | Settings → Security and login → Developer mode → Plugins → + | Name it Argorant, paste the URL under Connection, OAuth. [Guide](/docs/agents/chatgpt) | | Codex | `~/.codex/config.toml` or Plugins | One config block, or the Argorant plugin with the connection and five skills. [Guide](/docs/agents/codex) | | Custom runtime | Any MCP client with OAuth | Point at the URL, complete the flow, call `argorant_account` first. | ## First calls [#first-calls] 1. `argorant_account` shows the connected account, the plan, the credits, the scopes and what is left of today's limits. 2. `argorant_count_people` and `argorant_preview_people` are free and safe. 3. Anything that spends credits or sends email asks the agent to confirm with the user first; the tool descriptions say so and the annotations mark them. # Cursor and other clients URL: https://docs.argorant.com/docs/agents/cursor-and-others Any MCP client that speaks streamable HTTP with OAuth can connect. Cursor, Windsurf, VS Code, Gemini CLI, and your own runtime. The server follows the standard. It speaks streamable HTTP at `https://mcp.argorant.com/mcp` and uses OAuth 2.1 with PKCE and dynamic client registration. If your client asks for a URL and can open a browser for sign-in, it works. ## Cursor [#cursor] **Settings → MCP → Add new global MCP server**, or put this in `~/.cursor/mcp.json`: ```json { "mcpServers": { "argorant": { "url": "https://mcp.argorant.com/mcp" } } } ``` ## VS Code (Copilot agent mode) [#vs-code-copilot-agent-mode] `.vscode/mcp.json`: ```json { "servers": { "argorant": { "type": "http", "url": "https://mcp.argorant.com/mcp" } } } ``` ## Windsurf [#windsurf] `~/.codeium/windsurf/mcp_config.json`: ```json { "mcpServers": { "argorant": { "serverUrl": "https://mcp.argorant.com/mcp" } } } ``` ## Gemini CLI [#gemini-cli] ```bash gemini mcp add --transport http argorant https://mcp.argorant.com/mcp ``` ## Your own runtime [#your-own-runtime] Use any MCP SDK. Discovery lives at `https://mcp.argorant.com/.well-known/oauth-protected-resource`; register a client at the authorization server's registration endpoint, run the authorization code flow with PKCE, then call `argorant_account` first. Every tool and its annotations are listed on [Tools](/docs/agents/tools). ## No MCP at all [#no-mcp-at-all] The REST API and the CLI are the same engine. An agent that can run a shell gets everything with `npx argorant … --json`. # Agents and MCP URL: https://docs.argorant.com/docs/agents A hosted MCP server that lets Claude, ChatGPT, Codex or your own agent run the whole outreach job under your account, your scopes and your credits. ```text https://mcp.argorant.com/mcp ``` Point a client at that URL and approve one sign-in. The agent can then size a market, look at the people, save a list, get checked emails and phone numbers, find one email, check your own list, build and launch a campaign from your mailboxes, answer the replies, order new mailboxes and buy credits, always asking you before it spends or sends. It uses the same operations as the REST API and the command line, with the same limits and the same credit balance. > How many VP Sales contacts can we reach at SaaS companies in Germany? Save them, write a two-step sequence, use all my mailboxes and show me what blocks a launch. > > The agent calls `argorant_count_people` (8,412), `argorant_create_list`, `argorant_create_campaign`, `argorant_set_campaign_emails`, `argorant_add_campaign_leads`, `argorant_set_campaign_senders` and `argorant_get_campaign` (nothing blocks the launch), then asks you before it launches. ## Prompts that work [#prompts-that-work] * "I run a commercial cleaning business in London. Find 30 local businesses I could approach and the people responsible for choosing their cleaning provider, with verified work emails." * "I'm a freelance web designer. Find 25 independent hotels in Portugal and the owners or marketing managers I could contact about my services. Help me set up a campaign end to end." * "Here's my website: example.com. Suggest the types of companies I should sell to, show me 25 matching prospects, and help me prepare an introductory email." * "I sell coffee wholesale. Find independent cafés in Manchester and the owners or buyers I should contact about stocking our coffee." * "Find the person responsible for partnerships at Acme and their verified business email address." * "Find 1,000 founders of UK software companies with 10 to 50 employees. Save their company details and verified work emails to a prospect list." * "Check the email addresses in this uploaded list. Separate valid addresses from invalid or uncertain results before I use it for outreach." * "Help me launch an outreach campaign for my bookkeeping business. Find 500 relevant business owners, draft an introduction and two follow-ups, and prepare the campaign using my connected inboxes. Show me the audience and messages before sending." * "Schedule the campaign using my connected Google or Microsoft inboxes. Send on weekdays and show me the final sending schedule." ## Set up your client [#set-up-your-client] Claude.ai and Claude Desktop: one custom connector, one sign-in. One command for you, or a `.mcp.json` for the whole project. Developer mode first, then a custom connection with OAuth. Works on personal and business accounts that allow it. One block in config.toml, or the Argorant plugin with five skills for the whole flow. Cursor, Windsurf, VS Code, Gemini CLI, your own runtime: the same URL and OAuth. # Security and scopes URL: https://docs.argorant.com/docs/agents/security What an agent connected over MCP can see, what it must be granted before it spends or sends, and how to take that grant away. Everything here applies to the connector at `https://mcp.argorant.com/mcp`. ## Boundaries [#boundaries] * A connector is bound to one signed-in Argorant account. Nothing is anonymous; every call is attributable. * Counts, coverage and masked previews are free. Preview rows never carry emails, phones or profile URLs. * Reveals, enrichment and exports run against the connected workspace's plan and credit balance. * Campaign tools act on the connected workspace only. Launching and replying send real email, and buying credits or mailboxes charges money; those tools are marked so clients ask you first. * Workspaces are kept apart. An agent cannot list or touch another workspace's campaigns, leads or replies. ## Scopes [#scopes] | Scope | Cost | Unlocks | | -------------------------- | ------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------- | | `argorant:read_counts` | Free | Counts, account, reading campaigns, the inbox, mailboxes and webhooks | | `argorant:search_segments` | Free | Coverage search and masked previews | | `argorant:manage_lists` | Free, except mailbox orders and credit purchases after a yes | Saved lists, campaign changes, launch, replies, statuses, blocklist, webhooks, mailbox orders, credit purchases | | `argorant:verify_emails` | Half a credit per fresh check | Check lists you already have; addresses checked recently are free | | `argorant:create_exports` | Credits | Export jobs and list exports | | `argorant:unlock_contacts` | Credits | Reveals, phone numbers, person enrichment, the email finder | ## Tool annotations [#tool-annotations] Every tool declares `readOnlyHint`, `openWorldHint` and `destructiveHint`. Read tools update private usage records and are therefore not marked read-only; `argorant_launch_campaign`, `argorant_inbox_reply`, `argorant_delete_campaign`, `argorant_set_campaign_emails` and `argorant_update_campaign` are destructive; anything that checks emails or sends email is open-world. ## Revoking access [#revoking-access] Disconnect the connector in the client, or revoke the grant at **app.argorant.com/profile → Connected apps**. Rotating or deleting an API key does not affect MCP grants, and vice versa. # Tools URL: https://docs.argorant.com/docs/agents/tools Every MCP tool with what it does, its annotations and what it can cost. Names are exact. A client may prefix them (for example `mcp__argorant__argorant_count_people`). Hints tell your AI app how careful to be. **read-only** tools only look at your own data: they change nothing, spend nothing and contact no one, so the app can run them without asking. Every tool that spends credits, sends email or changes something keeps asking for your approval. ## Read and preview [#read-and-preview] | Tool | What it does | Hints | | ------------------------- | --------------------------------------------------------------------------------------------------------- | --------- | | `argorant_account` | Shows who is connected, the credits left and today's limits. | read-only | | `argorant_count_people` | Counts the people who match a search. Free. | read-only | | `argorant_company_people` | Shows how many people Argorant has at one company, with a few roles and the contact details hidden. Free. | read-only | | `argorant_preview_people` | Shows a few matching people with their contact details hidden, so you can check the search fits. Free. | read-only | | `search` | Looks up how many contacts Argorant has for a company domain or a short text. Free. | read-only | | `fetch` | Opens a result from `search`: the count and a few people with contact details hidden. Free. | read-only | ## Reveal, enrich, export [#reveal-enrich-export] | Tool | What it does | Hints | | ---------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------- | | `argorant_reveal_people` | Shows the full contact details of a small group of people: name, work email and profile link. 1 credit per person whose working email is new to you. With `include_phones` it also adds phone numbers: 10 credits per phone number returned, nothing if none is found. | destructive, open-world | | `argorant_enrich` | Looks up one person by email, or by name and company domain, or one company by its domain. 1 credit for a new working email; a company lookup is free. With `include_phones` it also adds the person's phone number: 10 credits if one is found, nothing if not. | destructive, open-world | | `argorant_create_export` | Makes a spreadsheet (CSV) of everyone who matches a search. 1 credit per person with a working email. With `include_phones`, each phone number in the file costs 10 more credits. | destructive, open-world | | `argorant_export_status` | Shows how far an export is and whether it is ready. | read-only | | `argorant_export_batch_status` | Shows how far a large export, split into several files, is. | read-only | | `argorant_download_export_preview` | Reads the first part of a finished export file. It shows real contact details. | safe | ## Phone numbers [#phone-numbers] Phone numbers (direct dials and mobiles) are never included unless you ask for them. Your AI app adds them only when it sets `include_phones` on `argorant_reveal_people`, `argorant_enrich`, `argorant_create_export` or `argorant_export_list`, and it asks you first. * A phone number costs 10 credits, and only when a number is actually returned. * People without a number cost nothing. * Numbers you already unlocked, in the app, the API, the CLI or here, are free. * Phone numbers come with the Pro plan and higher. * Every result says, per person, whether a number came back and what it cost. Company and HQ numbers stay free where Argorant already shows them. The same rule applies in the app and in the [API](/docs/reference) (`POST /api/v1/people/phones`). ## Lists [#lists] | Tool | What it does | Hints | | ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------- | | `argorant_create_list` | Saves a search, or chosen people, as a list in your workspace. Free. | safe | | `argorant_list_status` | Shows a saved list's size and a few of its people. | read-only | | `argorant_export_list` | Makes a spreadsheet (CSV) of a saved list. 1 credit per person with a working email. With `include_phones`, each phone number in the file costs 10 more credits. | destructive, open-world | | `argorant_list_lists` | Lists your saved lists, newest first, with their size. Free. | read-only | | `argorant_rename_list` | Gives a saved list a new name. | safe | | `argorant_delete_list` | Deletes a saved list for good. The people in it are not touched. | destructive | ## Find work emails [#find-work-emails] | Tool | What it does | Hints | | ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------------------- | | `argorant_find_email` | Finds one person's work email from their name and company domain. 1 credit when found, 1 credit when the company accepts every address (the address is marked unconfirmed), 0.25 credits when nothing is found. Wrong input and companies that cannot be reached cost nothing. | destructive, open-world | | `argorant_find_emails` | Finds work emails for a list of up to 1,000 people per call, within a spending limit you approved (`max_credits`). Same prices per person. | destructive, open-world | | `argorant_find_emails_status` | Shows how far a list is, what it found and what it cost. Spends nothing. | read-only | | `argorant_manage_find_emails` | Continues a paused list, optionally with a higher limit, or cancels it. Continuing spends credits. | destructive, open-world | ## Verify your own list [#verify-your-own-list] | Tool | What it does | Hints | | ------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------- | | `argorant_quote_verification` | Prices the check of an email list you own: how many addresses, how many are already known and free, and the most it can cost (half a credit per new check). Nothing starts. | safe | | `argorant_start_verification` | Starts the check you approved, never above the approved price. | destructive, open-world | | `argorant_verification_status` | Shows how far a check is, the results and what it cost. | read-only | Connections made before 2026-09-19 need to be reconnected once to use these. ## Campaigns [#campaigns] | Tool | What it does | Hints | | ------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------- | | `argorant_list_campaigns` | Lists your campaigns with how many people each one has reached. | read-only | | `argorant_get_campaign` | Shows one campaign with its emails, its sending mailboxes and anything that still blocks the launch. | read-only | | `argorant_create_campaign` | Creates a new draft campaign. Nothing is sent. | safe | | `argorant_update_campaign` | Changes a campaign's settings. | destructive | | `argorant_set_campaign_emails` | Sets the emails the campaign sends, step by step. | destructive | | `argorant_set_campaign_subsequences` | Sets follow-up emails that start when a reply contains a word you choose, up to 5 sets. | destructive | | `argorant_set_campaign_personalization` | Sets up a personal line for each contact: what it says (up to 4,000 characters), its length (20 to 300 characters) and the line used when nothing is known. | destructive | | `argorant_campaign_personalization_status` | Shows how many personal lines are written and which contacts still use the fallback line. | read-only | | `argorant_set_lead_custom_fields` | Saves the personal lines your AI app wrote, for up to 5,000 contacts at a time. Lines a contact already has are kept unless the AI app asks to overwrite them. | destructive | | `argorant_add_campaign_leads` | Adds people to a campaign. 1 credit per new person from Argorant data. Phone numbers are never copied into a campaign. Private addresses (free mail, home internet) stay unless you ask for business emails only (`exclude_private_emails`). | open-world | | `argorant_list_campaign_leads` | Lists the people in one of your campaigns. | read-only | | `argorant_remove_campaign_lead` | Stops a campaign from emailing one person. | destructive | | `argorant_set_campaign_senders` | Chooses which of your connected mailboxes send the campaign. | safe | | `argorant_remove_campaign_sender` | Takes one mailbox off a campaign. | safe | | `argorant_launch_campaign` | Starts, pauses or stops a campaign. Starting it sends real email from your mailboxes. | destructive, open-world | | `argorant_delete_campaign` | Deletes a campaign for good. | destructive | ## Inbox [#inbox] | Tool | What it does | Hints | | ------------------------------ | ---------------------------------------------------------------------------------------------------------- | ----------------------- | | `argorant_inbox` | Lists the replies to your campaigns. | read-only | | `argorant_inbox_thread` | Shows one conversation in full. | read-only | | `argorant_inbox_reply` | Sends a reply from your mailbox. It goes out right away. | destructive, open-world | | `argorant_inbox_forward` | Forwards a conversation, with its history and attachments, to up to ten addresses. It goes out right away. | destructive, open-world | | `argorant_inbox_classify` | Labels a reply, for example interested or not interested. | safe | | `argorant_reply_statuses` | Lists the labels you can give replies. | read-only | | `argorant_create_reply_status` | Adds a new label for replies. | safe | | `argorant_update_reply_status` | Changes the name, colour or description of one of your own reply labels. | safe | | `argorant_delete_reply_status` | Deletes one of your own reply labels. Replies that had it lose the label. | destructive | ## Analytics, mailbox settings, blocklist [#analytics-mailbox-settings-blocklist] | Tool | What it does | Hints | | ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------- | | `argorant_campaign_analytics` | Shows a campaign's results day by day: sent, replies, bounces. | read-only | | `argorant_update_inbox` | Changes a mailbox's settings, such as its daily limit or warm-up. | destructive | | `argorant_blocklist` | Lists the addresses and domains you never want to email, 50 at a time by default (up to 1,000 a page), with search and blocks for single campaigns. | read-only | | `argorant_block` | Blocks one address or domain, or up to 5,000 per call, in every campaign or only in the campaigns you name, and stops emails to them. A dry run counts first. | destructive | | `argorant_unblock` | Takes one entry, or up to 5,000 per call, off your blocklist, so campaigns may email them again. | destructive | ## Mailboxes [#mailboxes] | Tool | What it does | Hints | | ----------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------- | | `argorant_list_inboxes` | Lists your connected mailboxes with their health and daily limits. | read-only | | `argorant_connect_google_workspace` | Lists the mailboxes of your Google Workspace and connects the ones you choose. | open-world | | `argorant_test_smtp_mailbox` | Checks that Argorant can sign in to a mailbox from any other provider, for sending and for reading replies, and says what to fix. Nothing is saved. | read-only, open-world | | `argorant_connect_smtp_mailbox` | Connects one mailbox from any other provider, or up to 25 at once, after the sign-in works. The password is stored safely and never shown again. | open-world | | `argorant_disconnect_inbox` | Disconnects a mailbox. Its campaigns stop sending from it. | destructive | ## New inboxes [#new-inboxes] The assistant shows you the whole quote and orders only after your explicit yes. The order returns a checkout link that you pay yourself; nothing is bought before that payment. Only the workspace owner can order or cancel. Warm-up is included in every plan; switch it on per mailbox with `argorant_update_inbox`. | Tool | What it does | Hints | | ----------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------- | | `argorant_suggest_inbox_domains` | Suggests free domain names made from your website or brand, with their prices. Nothing is reserved. | read-only, open-world | | `argorant_quote_inboxes` | Stores a 24-hour quote for new mailboxes on new domains: every domain with its prices, the mailboxes, due today and the recurring total. Nothing is ordered or charged. | open-world | | `argorant_order_inboxes` | After your yes to the quote, creates the order and returns the checkout link you pay. Setup starts once the payment is confirmed. | destructive, open-world | | `argorant_inbox_order_status` | Shows your mailbox orders, their progress, domains and renewal prices. | read-only | | `argorant_cancel_inbox_bundle` | Stops billing for a bundle of mailboxes; they work until the paid period ends and are then deleted. | destructive | | `argorant_cancel_inbox_domain` | Stops a domain's renewal; it works until its expiry date. | destructive | | `argorant_set_inbox_domain_renewal` | Stops a domain's renewal or turns it back on. Nothing is charged now either way. | destructive | ## Webhooks [#webhooks] Webhooks come with the Pro plan. Argorant calls your address when something happens, for example a reply, a positive reply, a bounce or an export that is ready. | Tool | What it does | Hints | | ------------------------- | ------------------------------------------------------------------- | ----------- | | `argorant_webhooks` | Lists your webhooks and the events you can choose. | read-only | | `argorant_create_webhook` | Adds a webhook to a public https address for the events you choose. | open-world | | `argorant_test_webhook` | Sends a test event to one of your webhooks. | open-world | | `argorant_delete_webhook` | Deletes a webhook. | destructive | ## Credits [#credits] Argorant is the cheapest way to get validated B2B contacts. Compare the packs below with [our comparison pages](https://argorant.com/compare). The assistant shows you the price and buys only after your explicit yes. You get a payment link that you pay yourself, unless your workspace allows the saved card, which is then charged within the limits you set in Settings. | Tool | What it does | Hints | | --------------------------- | ---------------------------------------------------------------------------------------------------------- | ----------------------- | | `argorant_credit_packs` | Shows the credit packs and their prices: 500 for $17.50, 5,000 for $69, 25,000 for $199, 100,000 for $499. | read-only | | `argorant_quote_credits` | Makes a quote for one pack and says how it would be paid. Nothing is bought. | safe | | `argorant_buy_credits` | After your yes to the quote, buys the pack with a payment link or the saved card. | destructive, open-world | | `argorant_credit_purchases` | Shows your credit purchases and whether each one is paid. | read-only | ## Send to other tools [#send-to-other-tools] Connect the sending tool you already use once in Argorant, under Settings, Integrations, with that tool's own API key. The assistant never asks for that key. It can then send a campaign's people or an export into one of your campaigns there. People who bounced, unsubscribed or are blocked are never sent, and your campaign there is not started. | Tool | What it does | Hints | | ---------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- | | `argorant_list_integrations` | Shows the tools you connected, and the campaigns inside one of them. | read-only | | `argorant_push_to_integration` | After your yes, sends a campaign's people or an export into a campaign in a connected tool. Free from the Pro plan; an export costs credits when it runs. | open-world | | `argorant_integration_push_status` | Shows how a send stands and how many people went over. | read-only | Parameters for each campaign and inbox tool mirror the REST endpoints in the [API reference](/docs/reference); the data tools take the shared [filters](/docs/guides/find-and-export#filters). # Authentication URL: https://docs.argorant.com/docs/getting-started/authentication API keys, the base URL, what each key scope allows, and how AI agents sign in without a key. ## Base URL [#base-url] ```text https://app.argorant.com/api/v1 ``` ## API keys [#api-keys] Sign in at [app.argorant.com/profile](https://app.argorant.com/profile) and create a key under API keys. Keys start with `ag_live_` and are shown once. Give each key the name of the thing that uses it, such as `zapier`, `ci` or `laptop`, so you can revoke one without breaking the others. Send the key with every call: ```bash curl "https://app.argorant.com/api/v1/account" \ -H "Authorization: Bearer $ARGORANT_API_KEY" ``` The answer tells you who the key acts as, your plan, your credits, how many requests a minute the key may send and what is left of today's limits. Call it before a large job. API keys work during the 14-day trial, on every plan and with pay-as-you-go credits. The command line tool reads the same key from `npx argorant login` or from the `ARGORANT_API_KEY` variable. ## Scopes [#scopes] A key created in the app holds every scope below. A narrower key gets `403` with the code `scope_missing` when it calls something outside its scopes. | Scope | Allows | Can cost | | -------------------------- | ------------------------------------------------------------------------------------------------------------ | -------------------------------------- | | `argorant:read_counts` | Counts, word lists, account, reading campaigns, the inbox, mailboxes and webhooks | Nothing | | `argorant:search_segments` | Masked previews of people and companies | Nothing | | `argorant:manage_lists` | Lists, campaigns, launching, answering replies, statuses, mailboxes, the blocklist, webhooks, mailbox orders | Mailbox orders cost money, after a yes | | `argorant:unlock_contacts` | Reveals, phone numbers, person enrichment, the email finder | Credits | | `argorant:create_exports` | Exports and list exports | Credits | | `argorant:verify_emails` | Checking your own lists | Credits, half a credit per fresh check | ## AI agents sign in, they never see the key [#ai-agents-sign-in-they-never-see-the-key] MCP clients such as Claude and ChatGPT connect to `https://mcp.argorant.com/mcp` and sign in with OAuth 2.1 (authorization code with PKCE). They act for your account with the scopes you approve, and your API key never goes into a chat. See [Connect a client](/docs/agents/connect). ## Permissions inside a workspace [#permissions-inside-a-workspace] A key acts as the person who created it. Owners and members see only their own workspace. Some actions, such as ordering mailboxes, are for the workspace owner; a member gets `403` with a plain message saying so. Items of other workspaces always answer `404 not_found`, the same as items that do not exist. # Errors and limits URL: https://docs.argorant.com/docs/getting-started/errors-and-limits The one error shape, every error code, the request id, request limits per plan, limits on searches and counts, daily limits, pages and safe retries. {/* Generated by scripts/gen-facts-pages.mjs from the reference catalogue. Do not edit by hand. */} ## One error shape [#one-error-shape] Every error answer looks the same. Read `error.code` to decide what to do and show `error.message` to people. The message is one plain sentence. ```json { "error": { "code": "insufficient_credits", "message": "Revealing these people costs 1 credit each and the account has none left. Buy credits or upgrade.", "details": { "needed": 25, "balance": 0 } }, "request_id": "req_8f2c1d9e0b7a4c3e9f1a2b3c4d5e6f70", "detail": "..." } ``` `detail` holds the older form of the error for clients written before this shape. New code should read `error`. ## Error codes [#error-codes] | Code | Status | What it means and what to do | | -------------------------------- | ------ | ---------------------------------------------------------------------------------------------------------------------------------------------------- | | `invalid_request` | 400 | The request is missing something or a value is wrong. The message says what to fix. | | `launch_blocked` | 400 | The campaign cannot launch yet. details.blockers lists what is missing. | | `unauthorized` | 401 | No API key, or the key is wrong or revoked. | | `api_key_required` | 401 | This route needs an API key or a connector sign-in, not a browser session. | | `plan_required` | 402 | The account's plan does not include this. The message names the plan that does. | | `insufficient_credits` | 402 | Not enough credits for this call. details says how many are needed. Nothing was charged. | | `scope_missing` | 403 | The key lacks a scope this call needs. Create a key with that scope. | | `permission_missing` | 403 | Your role in the workspace does not allow this action. | | `forbidden` | 403 | This action is not allowed for this account. | | `not_found` | 404 | No such item in your workspace. Items of other workspaces answer the same way. | | `route_not_found` | 404 | No such endpoint. Check the path against the reference. | | `method_not_allowed` | 405 | The path exists but not with this HTTP method. details.allowed lists the methods. | | `conflict` | 409 | The item is in a state that does not allow this, for example deleting a running campaign. | | `idempotency_conflict` | 409 | This Idempotency-Key was already used with a different body. | | `idempotency_in_progress` | 409 | A request with this Idempotency-Key is still running. Wait and retry. | | `gone` | 410 | The item expired, for example an export file older than its keep time. | | `quote_expired` | 410 | The quote is too old. Get a new quote and confirm again. | | `validation_error` | 422 | A field has the wrong type or is missing. details.fields lists each problem. | | `access_key_activation_required` | 428 | This invited access key is not active yet. Confirm the email in details.claim\_url first. | | `rate_limited` | 429 | Too many requests this minute. Wait Retry-After seconds. | | `daily_limit_reached` | 429 | The key's daily limit for this kind of call is used up. It resets at midnight UTC. | | `internal_error` | 500 | Something failed on our side. Retry; quote the request id if it keeps failing. | | `unavailable` | 503 | A part of the service is busy or paused. Retry in a minute. | | `confirmation_required` | 400 | A purchase or an order needs confirmed=true, sent only after the person who pays said yes. | | `invalid_webhook_url` | 400 | The webhook address must be a public https\:// address. | | `phones_not_in_plan` | 402 | Phone numbers come with the Pro plan. Nothing was charged. | | `card_not_charged` | 402 | The saved card was not charged. Nothing was bought; pay through a payment link instead. | | `owner_only` | 403 | Only the workspace owner can do this, for example order or cancel mailboxes. | | `quote_not_found` | 404 | The quote does not exist or belongs to someone else. Get a new quote. | | `charge_in_progress` | 409 | This quote is being charged right now. Check the purchase in a moment. | | `not_enough_names` | 409 | Not enough free domain names were found. Send some domains yourself. | | `not_paid` | 409 | The order is not paid yet, so there is nothing to cancel. | | `reason_required` | 422 | Cancelling mailboxes needs a reason from the listed choices. | | `not_connected` | 409 | That tool is not connected yet. Connect it in Settings, Connected tools first. | | `unsupported_tool` | 409 | This connected tool cannot receive people directly. Send it an export from the Exports page instead. | | `tool_key_rejected` | 409 | The connected tool did not accept the saved key. Connect it again in Settings, Connected tools. | | `price_mismatch` | 409 | The price you showed the person is not the quoted price. Show the quoted price and ask again. | | `quote_other_session` | 409 | The quote was made with another key or connection. Ask for a new quote here and confirm again. | | `export_failed` | 409 | The export did not finish, so there is nothing to send. Run the export again. | | `sign_in_failed` | 422 | The mail server did not accept the sign-in, so the mailbox was not connected. details.test says for sending and for reading replies what went wrong. | Some operations add a code of their own, such as `confirmation_required` or `quote_not_found`. Each operation lists its codes in the [reference](/docs/reference). Treat a code you do not know by its HTTP status. ## The request id [#the-request-id] Every answer carries an `X-Request-Id` header, and every error repeats it as `request_id`. Send your own id in the `X-Request-Id` header (8 to 64 letters, digits, dots, dashes or underscores) to find a call in your own logs. Quote the id when you ask for help. ## Requests per minute [#requests-per-minute] Each key may send this many requests a minute, and up to the second number in any 10 seconds. | Plan | Requests a minute | In 10 seconds | | --------------------------------------------- | ----------------- | ------------- | | 14-day trial or pay as you go, API key or CLI | 30 | 15 | | 14-day trial or pay as you go, AI assistant | 60 | 20 | | Starter | 60 | 15 | | Pro | 240 | 60 | | Scale | 600 | 150 | | Hyperscale | 1,200 | 300 | Every answer to a key call carries `X-RateLimit-Limit` (requests a minute), `X-RateLimit-Remaining` (requests left this minute) and `X-RateLimit-Reset` (seconds until the minute starts again). Above either limit you get `429 rate_limited` with a `Retry-After` header. Wait that many seconds, then try again. ## Searches and counts [#searches-and-counts] Searches, counts and previews are free. They are limited per account, across all its keys and the connector, so a second key does not add more. | Plan | A minute | Counts a day | Preview rows a day | | --------------------------------------------- | -------- | ------------ | ------------------ | | 14-day trial or pay as you go, API key or CLI | 10 | 500 | 500 | | 14-day trial or pay as you go, AI assistant | 20 | 1,000 | 1,000 | | Starter | 30 | no limit | no limit | | Pro | 60 | no limit | no limit | | Scale | 90 | no limit | no limit | | Hyperscale | 120 | no limit | no limit | During the trial, searches and counts also carry `X-RateLimit-Daily-Limit` and `X-RateLimit-Daily-Remaining`. A preview holds up to 10 people a call. ## Daily limits per key [#daily-limits-per-key] During the trial and on pay as you go each key also has daily limits. On a plan only the email finder has one; credits bound the rest. Daily limits reset at midnight UTC. `GET /api/v1/account` shows what is left today. | What | Per day | Per call | | -------------------- | --------------------------- | ------------------------------------ | | Revealed people | 100 (no limit on a plan) | 25 | | Export rows | 50,000 (no limit on a plan) | 50,000 per file, 500,000 per batch | | Email finder lookups | 2,000 | 30 a minute, lists up to 10,000 rows | Above a daily limit you get `429 daily_limit_reached`. For more people than the daily reveal limit, save a list, export it or add it to a campaign; those paths are made for thousands of people. ## Pages [#pages] Every list takes `limit` and `cursor`. The answer keeps its own key (for example `campaigns` or `people`) and adds `total`, `limit`, `offset`, `next_cursor` and `has_more`. Pass `next_cursor` as `cursor` to get the next page; it is `null` on the last page. `offset` works too, if you prefer counting rows yourself. ```bash curl "https://app.argorant.com/api/v1/campaigns?limit=25" -H "Authorization: Bearer $ARGORANT_API_KEY" curl "https://app.argorant.com/api/v1/campaigns?limit=25&cursor=bzoyNQ" -H "Authorization: Bearer $ARGORANT_API_KEY" ``` When `total_is_estimate` is `true`, `total` is the least there is, for example when a list reached its largest size. ## Safe retries [#safe-retries] Send an `Idempotency-Key` header with any write: creating, changing, deleting, answering, forwarding and anything that spends credits or money. Use a new random value for each new action and the same value when you retry it. * The same key and the same body within 24 hours return the first answer, with the header `Idempotent-Replayed: true`. Nothing is done twice. * The same key with a different body answers `409 idempotency_conflict`. * While the first request is still running, a retry answers `409 idempotency_in_progress`. Wait a moment and try again. * Errors are not stored, so you can fix the problem and retry with the same key. ```bash curl -X POST "https://app.argorant.com/api/v1/exports" \ -H "Authorization: Bearer $ARGORANT_API_KEY" \ -H "Idempotency-Key: export-cfo-germany-2026-10-07" \ -H "Content-Type: application/json" \ -d '{"filters":{"title":"CFO","country":"Germany"},"limit":500}' ``` ## Campaigns that cannot launch [#campaigns-that-cannot-launch] `POST /api/v1/campaigns/{id}/launch` answers `launch_blocked` while something is missing, for example an email, a mailbox with room left today, or people. `details.blockers` lists each one in plain words. `GET /api/v1/campaigns/{id}` shows the same list as `launch_blockers`, so you can fix them before you try. # Introduction URL: https://docs.argorant.com/docs/getting-started/introduction What the Argorant API does, what is free, what costs credits, and how the API, the command line tool and the MCP server fit together. ## One account, three ways in [#one-account-three-ways-in] Everything Argorant does lives once, in the REST API at `https://app.argorant.com`. Every path starts with `/api/v1`. The command line tool and the MCP server call the same operations, so prices, limits and permissions are the same wherever you work. | Way in | Good for | How you sign in | | ------------ | -------------------------------------------------- | ------------------------------------------------------- | | REST API | Your own code, pipelines and tools | `Authorization: Bearer ag_live_...` | | Command line | The terminal, scripts and coding agents | `npx argorant login` or the `ARGORANT_API_KEY` variable | | MCP server | Claude, ChatGPT, Codex, Cursor and your own agents | Sign in once at `https://mcp.argorant.com/mcp` | Call `GET https://app.argorant.com/api/v1` without a key to see every operation the API offers. ## The cheapest way to get validated contacts [#the-cheapest-way-to-get-validated-contacts] Argorant is the cheapest way to get validated B2B contacts. With pay as you go, 100,000 credits cost $499, which is under half a cent per validated contact. On Hyperscale, 200,000 credits a month cost $649, about a third of a cent each. An email that fails the check costs nothing. Compare the prices yourself on [our comparison pages](https://argorant.com/compare) and the [alternatives](https://argorant.com/alternatives), for example Argorant and [ZoomInfo](https://argorant.com/compare/zoominfo-vs-argorant), [Cognism](https://argorant.com/compare/cognism-vs-argorant), [Hunter](https://argorant.com/compare/hunter-vs-argorant), [LeadIQ](https://argorant.com/compare/leadiq-vs-argorant), [Prospeo](https://argorant.com/compare/prospeo-vs-argorant), [Seamless](https://argorant.com/compare/seamless-vs-argorant) or [UpLead](https://argorant.com/compare/uplead-vs-argorant) side by side. ## The job, step by step [#the-job-step-by-step] ### Find [#find] Count and preview people by job title, seniority, industry, country, company size, keywords or the technology their company uses. Free. ### Get the contacts [#get-the-contacts] Reveal people, save them as a list or export a CSV. Every email is checked right before you get it. You pay one credit per person whose email passes, and nothing for the rest. Phone numbers cost 10 credits each, only when one is returned. ### Reach them [#reach-them] Turn a list into a campaign. Write the emails, add a personal line per person, choose the mailboxes that send, and launch. Argorant spreads the emails over the day and keeps each mailbox within its limit. ### Answer [#answer] Every reply from every campaign lands in one inbox. Read it, answer in the same thread, forward it, and mark it with a status such as interested or meeting booked. ## Things every call has in common [#things-every-call-has-in-common] * Answers are JSON. Lists take `limit` and `cursor` and answer with `total`, `next_cursor` and `has_more`. * Errors have one shape with a stable code. See [Errors and limits](/docs/getting-started/errors-and-limits). * Every write accepts an `Idempotency-Key`, so a retry never does the work twice. * Every answer carries `X-Request-Id`. Quote it if you ask for help. The OpenAPI document is at [/openapi.json](/openapi.json). The text for AI agents is at [/llms.txt](/llms.txt) and [/llms-full.txt](/llms-full.txt). # Buy credits from an agent URL: https://docs.argorant.com/docs/guides/buy-credits How a script or an AI agent buys credits safely. Show the packs, get a quote, ask the person who pays, then the saved card is charged within the workspace limits or you get a payment link. Credits come in four packs: 500 for $17.50, 5,000 for $69, 25,000 for $199 and 100,000 for $499. They are paid once, stay valid for 365 days and stay in the account even if a plan is cancelled. One credit is one contact; half a credit checks one email; a phone number costs 10. An agent never buys on its own. It always shows a quote and waits for a clear yes from the person who pays. ### Show the packs [#show-the-packs] ```bash curl "https://app.argorant.com/api/v1/credits/packs" -H "Authorization: Bearer $ARGORANT_API_KEY" ``` Add `?currency=eur` for euro prices. ### Get a quote [#get-a-quote] ```bash curl -X POST "https://app.argorant.com/api/v1/credits/quote" \ -H "Authorization: Bearer $ARGORANT_API_KEY" -H "Content-Type: application/json" \ -d '{"credits": 5000, "currency": "usd"}' ``` The quote has the price, a sentence to show (`summary`), and `payment`, which says how it would be paid. When `payment.saved_card.usable` is `true`, the saved card is charged right away after the yes. Otherwise the purchase returns a payment link. Nothing is charged by a quote. ### Ask [#ask] Show `summary` and, for the saved card, which card is charged. Wait for a clear yes. ### Buy [#buy] ```bash curl -X POST "https://app.argorant.com/api/v1/credits/purchases" \ -H "Authorization: Bearer $ARGORANT_API_KEY" -H "Content-Type: application/json" \ -d '{"quote_id": "2f8a1b3c-4d5e-4f70-8192-a3b4c5d6e7f8", "confirmed": true}' ``` With a usable saved card the answer is `status: paid` and the credits are in the account at once. A receipt goes to the workspace owner and the buyer. Without one, the answer is `status: awaiting_payment` with `checkout_url`. Give that link to the person who pays; the credits arrive as soon as they pay. `"pay_with": "link"` always asks for a link. ### Check [#check] ```bash curl "https://app.argorant.com/api/v1/credits/purchases/2f8a1b3c-4d5e-4f70-8192-a3b4c5d6e7f8" -H "Authorization: Bearer $ARGORANT_API_KEY" ``` A payment link shows `paid` once it was paid and `expired` when it ran out unpaid. ## Why it is safe [#why-it-is-safe] * The quote id is the key. Sending the same purchase again returns the first answer and never charges twice. * A saved card is used only when it was saved for purchases by the API and agents. The first payment through a link saves it, with a line on the payment page that says so. * The workspace decides in Settings, Billing whether agents may use the saved card, and can set a monthly limit and a limit per purchase. Above a limit the purchase gets a payment link instead. * A saved-card purchase must follow its quote within 15 minutes. After that, get a new quote. * A card that is declined or needs its holder to confirm is not charged; you get a payment link instead. Mailboxes on new domains are bought the same way with `POST /api/v1/inboxes/quote` and `POST /api/v1/inboxes/orders`. # Campaigns end to end URL: https://docs.argorant.com/docs/guides/campaigns-end-to-end Create the campaign, write the emails, add a list, choose your mailboxes and launch. Every step is one call, and nothing sends before the launch. Nothing sends until you call `launch`. The same steps exist as command line commands and MCP tools, so an agent can run the whole flow and ask the user before the launch. Send an `Idempotency-Key` header with each call so a retry never does the work twice. ### Check that a mailbox is connected [#check-that-a-mailbox-is-connected] ```bash curl "https://app.argorant.com/api/v1/inboxes" -H "Authorization: Bearer $ARGORANT_API_KEY" ``` No mailbox yet? Connect a Google Workspace in one step ([guide](/docs/guides/google-workspace)), Microsoft 365 in the app, or a mailbox from any other provider with its server settings ([guide](/docs/guides/smtp-mailboxes)). ### Create the campaign with its settings [#create-the-campaign-with-its-settings] ```bash curl -X POST "https://app.argorant.com/api/v1/campaigns" \ -H "Authorization: Bearer $ARGORANT_API_KEY" -H "Content-Type: application/json" \ -d '{ "name": "Q4 CFO outreach", "daily_limit": 40, "per_mailbox_daily_limit": 20, "timezone": "Europe/Berlin", "timezone_mode": "fixed", "window_start": "08:00", "window_end": "17:00", "skip_weekends": true, "gap_minutes_min": 60, "gap_minutes_max": 120, "planned_start_date": "2026-10-01", "tags": ["q4"] }' ``` Only `name` is required, and every setting can be changed later with `PATCH /api/v1/campaigns/{id}`. `timezone_mode: "lead"` sends in each person's local time. Campaigns send plain text, which reaches the inbox best. There is no unsubscribe line unless you set `include_unsubscribe` to `true`. ### Write the sequence [#write-the-sequence] ```bash curl -X POST "https://app.argorant.com/api/v1/campaigns/$ID/emails" \ -H "Authorization: Bearer $ARGORANT_API_KEY" -H "Content-Type: application/json" \ -d '{"emails":[ {"subject":"Quick question, {{first_name}}","body":"Hi {{first_name}},\n\nsaw {{company}} is hiring in finance. Worth a 10 minute call?\n\nBest"}, {"body":"Bumping this up in case it got buried.","delay_days":3,"same_thread":true} ]}' ``` The first email needs a subject. Follow-ups stay in the same thread by default and wait `delay_days` after the previous one. You can use `{{first_name}}`, `{{last_name}}`, `{{company}}`, `{{company_normalized}}` (the name people say), `{{title}}` and any column you sent with the people, such as `{{plan}}`. Write `{a|b}` to vary a phrase per person. Add `variants` to an email for other versions; they are sent in turn. A personal line per person is set up with `PUT /api/v1/campaigns/{id}/personalization`; see [Find and email 200 people](/docs/guides/find-and-email-200-people). ### Enroll the list [#enroll-the-list] ```bash curl -X POST "https://app.argorant.com/api/v1/campaigns/$ID/leads" \ -H "Authorization: Bearer $ARGORANT_API_KEY" -H "Content-Type: application/json" \ -d '{"list_id": 1240}' # {"input_rows": 1240, "inserted": 1188, "duplicates_skipped": 12, "skipped_not_valid": 40, "queued_for_verification": 0} ``` Or send your own `rows` with `email`, `first_name`, `last_name`, `company`, `title` and any column of your own. Every address is checked before it joins. When a list holds addresses that cannot be confirmed, the first answer asks which to take (`needs_choice`); call again with `"grades": ["valid"]` (recommended) or `["valid", "catch_all"]`. People from Argorant's data cost 1 credit each the first time; your own rows are free. Private addresses (free mail, home internet) are added like any other; send `"exclude_private_emails": true` for business emails only. ### Attach the senders [#attach-the-senders] ```bash curl -X POST "https://app.argorant.com/api/v1/campaigns/$ID/senders" \ -H "Authorization: Bearer $ARGORANT_API_KEY" -H "Content-Type: application/json" \ -d '{"all_connected": true}' ``` Or name specific `emails`. Emails are spread across the mailboxes, each within its own daily limit. ### Launch [#launch] ```bash curl "https://app.argorant.com/api/v1/campaigns/$ID" -H "Authorization: Bearer $ARGORANT_API_KEY" | jq .launch_blockers curl -X POST "https://app.argorant.com/api/v1/campaigns/$ID/launch" -H "Authorization: Bearer $ARGORANT_API_KEY" ``` `launch_blockers` is empty when the campaign can go. Before you launch, `POST /api/v1/campaigns/{id}/test-email` sends one test of an email to you, filled with a sample contact. Launch only after the user said yes. `pause` holds it, `stop` ends it, and `DELETE` removes a campaign that is not running. ## Watch it run [#watch-it-run] `GET /api/v1/campaigns/{id}/analytics?days=30` gives the daily numbers (sent, replies, positive replies, bounces, unsubscribes) with totals and rates. `GET /api/v1/campaigns/{id}` has the live counts. `GET /api/v1/campaigns/{id}/leads?status=replied` lists who answered, and `GET /api/v1/campaigns/{id}/replies` gives their messages. For replies across all campaigns use the [inbox](/docs/guides/replies-and-inbox). `GET /api/v1/campaigns/{id}/senders` lists the mailboxes that send it, with their status. ## Change the people in a running campaign [#change-the-people-in-a-running-campaign] `POST /api/v1/campaigns/{id}/leads/remove` takes many people out at once, chosen by status, replied, bounced, email domain, tag, addresses or a saved list. Send `"preview": true` first to see how many would go. People who already got an email stay unless you send `"include_contacted": true`. A large add or removal runs in the background: the answer is 202 with a job, and `GET /api/v1/campaigns/{id}/lead-jobs/{job_id}` says how far it has come. Personal lines for many people go in one file: `POST /api/v1/campaigns/{id}/leads/custom-fields/import` takes a CSV, JSON or NDJSON file with up to 200,000 rows (50 MB). Lines people already have are kept and listed with their row. To correct them, upload with `?overwrite=true`; a `clear` column (or `null` in JSON) takes a line away, and the person gets the fallback again. Every replaced line comes back in the answer, old and new. ## Folders [#folders] `GET /api/v1/folders` lists your folders, `POST /api/v1/folders` creates one and `PATCH /api/v1/folders/{id}` renames it. `POST /api/v1/campaigns/{id}/folder` with a `folder_id` files a campaign, and `null` takes it out again. Folders only sort campaigns; sending is not affected. ## Mailboxes and the blocklist [#mailboxes-and-the-blocklist] `GET /api/v1/inboxes` lists your mailboxes with filters for domain, status, tag and provider. `PATCH /api/v1/inboxes/{email}` sets a mailbox's daily limit, warm-up, whether it may send, its name or its time zone, and `DELETE` disconnects it. `POST /api/v1/inboxes/update` makes the same change for many mailboxes at once, chosen by domain, tag, status or address; it previews by default and changes nothing until you send `"preview": false`. `POST /api/v1/blocklist` with an address or a domain stops every email to it in your workspace; `DELETE /api/v1/blocklist/{id}` lifts that again. ## The same steps in the terminal [#the-same-steps-in-the-terminal] ```bash argorant campaigns create --name "Q4 CFO outreach" --daily-limit 40 --window 08:00-17:00 --timezone Europe/Berlin argorant campaigns emails set "Q4 CFO" --step 1 --subject "Quick question, {{first_name}}" --body-file step1.txt argorant campaigns emails set "Q4 CFO" --step 2 --body "Bumping this up." --delay-days 3 argorant campaigns leads add "Q4 CFO" --list 1240 argorant campaigns senders set "Q4 CFO" --all argorant campaigns test "Q4 CFO" --step 1 argorant campaigns launch "Q4 CFO" argorant campaigns leads remove "Q4 CFO" --not-replied --domains competitor.com --preview argorant campaigns folders create --name "Q4" argorant campaigns move "Q4 CFO" --folder Q4 argorant inboxes update --domains northgate-advisory.com --daily-limit 30 ``` # Command line URL: https://docs.argorant.com/docs/guides/cli Everything from the terminal with npx argorant. JSON output for scripts and agents, pages with a cursor, safe retries and exit codes you can act on. ```bash npx argorant login # paste a key from app.argorant.com/profile once npx argorant account # plan, credits, request limit, campaign emails ``` `npx` runs it without installing. To install it for good, run `npm install -g argorant`. The tool reads the key from `argorant login` or from the `ARGORANT_API_KEY` variable. ## Commands [#commands] | Command | What it does | | --------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `account` | Plan, credits, request limit and campaign emails | | `count "" [filters]` | Count matching people, free | | `search "" -n 10` | A masked preview, free | | `company ` | How many people at one company, free | | `companies count / search / people` | Companies that match your filters, free | | `lookup industries / countries / keywords / technologies / titles [text]` | The exact names to filter with, free | | `filters` | Every search filter with its flags and values, and which are ready now, free | | `reveal "" -n 25` | Full details with checked emails, uses credits | | `enrich --email a@b.com` / `--name "..." --domain d` / `--domain d` | Fill in one record | | `find "Jane Doe" --domain acme.com` / `find --file people.csv -o found.csv --max-credits 100` | Find work emails: 1 credit when found, 0.25 when nothing is found | | `find status / download / resume / cancel `, `find pricing` | Email finder lists and prices | | `lists ls / create / show / people / rename / rm / export` | Saved lists | | `export "" -n 1000 -o leads.csv` | A CSV of checked contacts, uses credits | | `exports ls / status / download` | Your exports | | `verify ` / `verify --file emails.csv -o checked.csv` | Check emails you already have | | `campaigns list / create / update / status / delete` | Campaigns and their settings | | `campaigns emails set --step 1 --subject ... --body-file f` | The emails | | `campaigns leads add --list ` / `leads list` / `leads remove` | The people in a campaign | | `campaigns leads remove --not-replied --status queued --preview` / `leads jobs ` | Take many people out at once, preview first; follow large adds and removals | | `campaigns personalize import lines.csv` | Personal lines for many people from one file | | `campaigns test --step 1` | One test email to you, adds nobody | | `campaigns folders` / `folders create --name` / `move --folder ` | Folders for campaigns | | `campaigns senders set --all` / `senders list` / `senders remove` | The sending mailboxes | | `campaigns launch / pause / stop ` | Start or stop sending; launch asks first, `-y` skips the question | | `campaigns analytics --days 30` / `campaigns replies ` | Results and replies of one campaign | | `inbox list / read / reply / forward / classify` | Every reply in one place | | `inbox stages / stages add / set / rm` | Your pipeline stages for replies | | `inboxes list --status needs_attention --tag t` / `set` / `disconnect` / `connect-google` | Your mailboxes | | `inboxes update --domains a.com --daily-limit 30` | Change many mailboxes at once, preview first | | `inboxes test-smtp / connect-smtp / connect-smtp --csv / presets` | Mailboxes from any provider ([guide](/docs/guides/smtp-mailboxes)); the password is asked for or read from an environment variable, never from the command line | | `inboxes quote / order / status / renewal` | New mailboxes on new domains | | `blocklist list / add / remove / job` | Addresses and domains never contacted. `list` shows 50 at a time (`--all`, `--search`, `--campaign`); `add` and `remove` take many values or `--file list.csv` (calls of 5,000), `--campaign` for single campaigns and `--dry-run` | | `credits packs / quote / buy / purchases` | Buy credit packs; asks first, then the saved card or a payment link | | `webhooks ls / add / set / test / deliveries / rm` | Events sent to your server, from the Pro plan | ## Filters [#filters] Every search command (`count`, `search`, `reveal`, `export`, `lists create`, adding to a list, `companies`) takes the same filters as the app, the API and the Claude connector. A comma means any of them. Each list filter has a leave-out twin that removes everyone the include filter would find for the same values, and both can be used together. | Include | Leave out | What it matches | | -------------- | ---------------------- | ------------------------------------------------------------------------------------------------------------- | | `--title` | `--exclude-title` | Job titles; short forms work both ways (CFO, Chief Financial Officer) | | `--keywords` | `--exclude-keywords` | Words that describe what the company does, such as fintech (`--keyword-scope people` for people's own skills) | | `--industry` | `--exclude-industry` | Industries in plain words | | `--country` | `--exclude-country` | Countries or regions such as DACH, Nordics, APAC | | `--state` | `--exclude-state` | States or provinces, by name or code | | `--city` | `--exclude-city` | Cities | | `--seniority` | `--exclude-seniority` | C-Level, VP, Director, Manager, Senior, Entry, Intern | | `--department` | `--exclude-department` | Sales, Marketing, Engineering, Finance and the other departments | | `--domain` | `--exclude-domain` | Company websites, such as stripe.com | How words match: * `--title-match words` (default) needs every word as a whole word, so Data does not match Database. `exact` needs the whole job title, so CEO does not match Founder & CEO. `contains` finds the text anywhere, also inside a word. * Keywords look everywhere by default: what the company does, people's skills and profiles, job titles and company names. `--keyword-scope company` looks only at what the company does (its tags, industry and description). There are more filters too, such as `--employees 51-200`, `--employees-min` and `--employees-max`, `--revenue 10m-50m`, `--revenue-min` and `--revenue-max`, `--company` (several companies: join the names with `|`), `--has-phone` and `--has-linkedin`. `npx argorant filters` lists every filter you can use. ```bash npx argorant count --title "VP Sales" --title-match exact --country DACH --exclude-country Switzerland npx argorant export --keywords fintech --exclude-keywords "venture capital, private equity" -n 500 -o fintech.csv ``` A saved list fills in the background. `lists show ` says whether it is still filling; adding to a list that is still filling waits for its turn. ## Built for scripts and agents [#built-for-scripts-and-agents] * `--json` on any command prints the API's answer as it is. * Lists print a cursor under each page. Pass it with `--cursor`, or add `--all` to read every page. * Every write gets a fresh `Idempotency-Key`. Pass `--idempotency-key ` to choose your own, so running the same command again returns the first answer instead of doing the work twice. * Exit codes are `0` for success, `1` for an error (and for `find` without a result), `2` for a missing or wrong key, `3` for a missing scope, `4` for a rate or daily limit, and `5` when a plan or more credits are needed. * Errors print the code, the plain message and the request id. * Commands that spend credits ask first at a terminal. They do not ask when the output is not a terminal or with `--yes` or `--json`, so check your `-n` in scripts. * A campaign can be named by its id or by the start of its name. ## From a search to a running campaign [#from-a-search-to-a-running-campaign] ```bash npx argorant lists create --name "UK finance leaders" --title "CFO, Finance Director" --country "United Kingdom" npx argorant campaigns create --name "UK finance Q4" --daily-limit 40 --timezone Europe/London npx argorant campaigns emails set "UK finance" --step 1 --subject "Quick question, {{first_name}}" --body-file step1.txt npx argorant campaigns leads add "UK finance" --list 1240 # business emails only: add --exclude-private-emails (free mail and home internet addresses are left out) npx argorant campaigns senders set "UK finance" --all npx argorant campaigns launch "UK finance" ``` # Find and email 200 people URL: https://docs.argorant.com/docs/guides/find-and-email-200-people From who you sell to, to a running campaign. Narrow the search to about 200 people, save them, write the emails with a personal line, add the people, choose the mailboxes and launch after a yes. This guide takes about 15 minutes. The searching is free. Adding the people costs 1 credit per person whose email passes the check, so about 200 credits. The emails themselves come with your plan. You need an API key, a plan or enough credits, and at least one connected mailbox. Check the mailboxes with `GET /api/v1/inboxes`. No mailbox yet? Connect a [Google Workspace](/docs/guides/google-workspace) in one step, connect Microsoft 365 in the app, connect a mailbox from [any other provider](/docs/guides/smtp-mailboxes), or order new mailboxes with `POST /api/v1/inboxes/quote`. ### Say who you sell to [#say-who-you-sell-to] Pick the job titles, the industry, the country and the company size. Use the free word lists to get the exact names: ```bash curl -G "https://app.argorant.com/api/v1/lookups/industries" -H "Authorization: Bearer $ARGORANT_API_KEY" --data-urlencode "q=logistics" ``` ### Narrow the count to about 200 [#narrow-the-count-to-about-200] ```bash curl -G "https://app.argorant.com/api/v1/people/count" -H "Authorization: Bearer $ARGORANT_API_KEY" \ --data-urlencode "title=Head of Operations,COO" --data-urlencode "industries=Truck Transportation" \ --data-urlencode "country=Netherlands" --data-urlencode "employee_range=51-200" # {"count": 214} ``` Too many? Add a city, a seniority or a smaller company size. Too few? Add more titles or countries. Counting is free, so try as often as you like. ### Look at a page of them [#look-at-a-page-of-them] ```bash curl -G "https://app.argorant.com/api/v1/people/search" -H "Authorization: Bearer $ARGORANT_API_KEY" \ --data-urlencode "title=Head of Operations,COO" --data-urlencode "industries=Truck Transportation" \ --data-urlencode "country=Netherlands" --data-urlencode "employee_range=51-200" ``` If the roles and companies look right, go on. If not, change the filters and count again. ### Save them as a list [#save-them-as-a-list] ```bash curl -X POST "https://app.argorant.com/api/v1/lists" -H "Authorization: Bearer $ARGORANT_API_KEY" \ -H "Idempotency-Key: ops-nl-list" -H "Content-Type: application/json" \ -d '{"name":"Ops leaders NL trucking","filters":{"title":"Head of Operations,COO","industries":"Truck Transportation","country":"Netherlands","employee_range":"51-200"}}' ``` Write down the `list_id`. The list fills itself in a few seconds. ### Create the campaign [#create-the-campaign] ```bash curl -X POST "https://app.argorant.com/api/v1/campaigns" -H "Authorization: Bearer $ARGORANT_API_KEY" \ -H "Idempotency-Key: ops-nl-campaign" -H "Content-Type: application/json" \ -d '{"name":"NL trucking ops Q4","daily_limit":40,"timezone":"Europe/Amsterdam","window_start":"08:30","window_end":"16:30"}' ``` It is a draft. New campaigns send plain text on weekdays and have no unsubscribe line unless you set `include_unsubscribe` to `true`. ### Write the emails [#write-the-emails] ```bash curl -X POST "https://app.argorant.com/api/v1/campaigns/$ID/emails" -H "Authorization: Bearer $ARGORANT_API_KEY" \ -H "Idempotency-Key: ops-nl-emails-1" -H "Content-Type: application/json" \ -d '{"emails":[ {"subject":"Planning at {{company_normalized}}","body":"Hi {{first_name}},\n\n{{custom_opener}}\n\nWe help trucking firms cut empty miles. Worth a short call next week?\n\nBest, Maria"}, {"body":"Hi {{first_name}}, just bringing this back up. Happy to send a two-minute video instead.","delay_days":3} ]}' ``` `{{company_normalized}}` is the company name people say. `{{custom_opener}}` is a personal line per person, set up next. Leftover text such as `[link]` comes back in `warnings`, and the campaign will not launch until it is gone. ### Add a personal line (optional) [#add-a-personal-line-optional] Set up the line once, with a fallback that reads well for anyone: ```bash curl -X PUT "https://app.argorant.com/api/v1/campaigns/$ID/personalization" -H "Authorization: Bearer $ARGORANT_API_KEY" \ -H "Content-Type: application/json" \ -d '{"variables":[{"name":"opener","instruction":"One sentence about something recent at their company.","fallback":"Hope the busy season treats you well."}]}' ``` Then `GET .../personalization` lists the people still on the fallback, with facts about their company, and `PATCH .../leads/custom-fields` saves the lines you or your agent wrote, up to 5,000 per call. A line someone already has stays unless you send `"overwrite": true`, so a second run never replaces lines by accident. An instruction can be up to 4,000 characters and each line 20 to 300 (`max_length`, 150 by default); see [Write personal lines](/docs/reference/campaigns/set-lead-custom-fields) for every limit. ### Add the people [#add-the-people] ```bash curl -X POST "https://app.argorant.com/api/v1/campaigns/$ID/leads" -H "Authorization: Bearer $ARGORANT_API_KEY" \ -H "Idempotency-Key: ops-nl-leads" -H "Content-Type: application/json" \ -d '{"list_id": 312}' ``` The first answer may be a question (`needs_choice: true`): how many addresses are confirmed and how many sit at domains that accept every address. Ask the user, then call again with `"grades": ["valid"]` (recommended) or `["valid", "catch_all"]`. Each new person costs 1 credit. People whose email fails the check are never added or charged. ### Choose the mailboxes [#choose-the-mailboxes] ```bash curl -X POST "https://app.argorant.com/api/v1/campaigns/$ID/senders" -H "Authorization: Bearer $ARGORANT_API_KEY" \ -H "Content-Type: application/json" -d '{"all_connected": true}' ``` ### Launch after a yes [#launch-after-a-yes] ```bash curl "https://app.argorant.com/api/v1/campaigns/$ID" -H "Authorization: Bearer $ARGORANT_API_KEY" ``` Show the user the emails, the number of people and the mailboxes. `launch_blockers` must be empty. Then, only after their yes: ```bash curl -X POST "https://app.argorant.com/api/v1/campaigns/$ID/launch" -H "Authorization: Bearer $ARGORANT_API_KEY" -H "Idempotency-Key: ops-nl-launch" ``` Replies arrive in the inbox. [Answer replies](/docs/guides/replies-and-inbox) shows how to read them, answer in the same thread and track your pipeline. `GET /api/v1/campaigns/$ID/analytics` gives the daily numbers. # Find, save and export URL: https://docs.argorant.com/docs/guides/find-and-export The filters every search shares, saved lists, CSV exports, phone numbers and enrichment, and what each one costs. ## Filters [#filters] Count, search, reveal, lists, exports and campaigns all use the same filters. The [word lists](/docs/reference/lookups) give the exact industry, country, keyword, technology and title names, with how many people carry each. | Filter | Example | How it works | | -------------------------------- | ------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `q` | `software companies selling to restaurants` | Plain words across name, title, company and description | | `title` | `CFO, Finance Director` | A comma means or. Knows abbreviations. `exclude_title` leaves titles out | | `seniority` | `C-Level,VP` | Owner, Founder, Partner, C-Level, VP, Director (also matches Head of), Manager, Senior, Entry, Intern | | `departments` | `Finance` | | | `industries` | `Software Development` | Exact names from the industries list; a pipe means or | | `keywords` | `logistics, freight` | Words that describe what the company does: its name, tags, industry and description. The widest filter for niches. `keyword_scope=people` looks at people's own skills instead, `keyword_scope=any` at both | | `technologies` | `Shopify` | What the company uses | | `employee_range` | `11-50,51-200` | Company size | | `country`, `state`, `city` | `Germany` or `DACH` | Names or regions such as Europe, DACH, Nordics | | `company_domain`, `company_name` | `stripe.com` | One company | | `has_phone`, `has_linkedin` | `true` | Only people with a phone number or a profile | | `business_email_only` | `true` | Only people whose email is at their company's own domain. Off unless you set it, so private addresses are left out only on request | | `exclude_assistants` | `false` | On by default. A title search leaves out assistant titles such as executive assistant or assistant to. Set it to `false` to keep them | Every count, search, list and export answer says what was applied beyond your own filters. `applied_filters` shows `business_email_only` when you switched it on, and `applied_defaults` shows whether assistant titles were left out and which ones. A saved list stores both, next to the request as you sent it (`filters.request`). Regions can overlap. Egypt is in both Middle East and Africa, Mexico is in both North America and LATAM, and Turkey counts as Middle East, not Europe. A person is counted once, even when several of the regions you name include their country. EMEA is Europe, the Middle East and Africa together. ## Saved lists [#saved-lists] A list keeps a search so you can export it or add it to a campaign later. ```bash curl -X POST "https://app.argorant.com/api/v1/lists" -H "Authorization: Bearer $ARGORANT_API_KEY" \ -H "Idempotency-Key: uk-finance-list" -H "Content-Type: application/json" \ -d '{"name":"UK finance leaders","filters":{"title":"CFO, Finance Director","country":"United Kingdom"}}' ``` A saved search answers at once. `snapshot_total` is the number of people when the count finishes in time; otherwise it is `null`, with `count_status` `pending` and a `status_url`. `GET /api/v1/lists/{id}/fill` shows the status, the counts, `progress_percent` and `eta_seconds`. Add `verbose=true` to see the saved search too. Send `record_ids` instead of `filters` to keep exactly the people you picked. `GET /api/v1/lists` shows all your lists, `GET /api/v1/lists/{id}/people` pages through the people in one, `POST /api/v1/lists/{id}/items` adds more, `PATCH` renames and `DELETE` removes a list. The `list_id` goes straight into `POST /api/v1/campaigns/{id}/leads`. ## Exports [#exports] An export builds a CSV in the background. ```bash curl -X POST "https://app.argorant.com/api/v1/exports" -H "Authorization: Bearer $ARGORANT_API_KEY" \ -H "Idempotency-Key: uk-finance-export" -H "Content-Type: application/json" \ -d '{"filters":{"title":"CFO, Finance Director","country":"United Kingdom"},"limit":500}' ``` Check `status_url` until `status` is `done`, then download from `download_url`. Every email is checked while the file is built, and you pay 1 credit per person whose email passes. People you exported before are left out unless you set `"exclude_previously_exported": false`, so you never pay twice for the same person. Above 50,000 rows the export becomes a batch of files; check it at `GET /api/v1/export-batches/{batch_id}`. `POST /api/v1/lists/{id}/export` exports a saved list the same way. ## Phone numbers [#phone-numbers] Add `"include_phones": true` to an export, or ask for numbers for up to 100 people with `POST /api/v1/people/phones` and their `record_ids`. A phone number costs 10 credits, only when one is returned, and numbers you already have are free. Phone numbers come with the Pro plan. `GET /api/v1/people/phones/pricing` shows the price and whether your plan includes them. ## Enrich one record [#enrich-one-record] When you already have an email, or a name and a company domain, `POST /api/v1/enrich` fills in the person: 1 credit for a match whose email passes, nothing for a miss, and the same person again is free. A company domain alone returns the company profile for free. # Find one email URL: https://docs.argorant.com/docs/guides/find-emails A person's name and company domain in, their work email out. One person at a time, or a list of up to 10,000 people, from the API, the command line, your AI assistant or the app. The email finder takes a first name, a last name and a company domain and gives back the person's work email. It works the same in the app (Email finder in the sidebar), the REST API, the command line and the MCP tools. ## What it costs [#what-it-costs] You pay per lookup, by what came back, from the same credits as everything else. | What came back | `status` | Price | | ---------------------------------------------------------------------------------------------------------------------------- | -------------------------------------- | ------------ | | Found and confirmed | `valid` | 1 credit | | The company's domain accepts every address, so none can be confirmed. You get the most likely one, marked `confirmed: false` | `catch_all` | 1 credit | | Nothing found | `not_found` | 0.25 credits | | Bad input, a domain without email, or a mail server that could not be reached right now | `400`, `no_mail_domain`, `retry_later` | Free | The quarter credit comes from a small prepaid balance. The first lookup that finds nothing takes 1 credit and keeps 0.75 for the next three. `GET /api/v1/email-finder/pricing` shows the prices, your balance and your limits. Treat `catch_all` addresses as a good guess. Send to them in smaller numbers and watch the bounces. ## One person [#one-person] ```bash curl -X POST "https://app.argorant.com/api/v1/email-finder/find" \ -H "Authorization: Bearer $ARGORANT_API_KEY" -H "Idempotency-Key: find-jane-doe-acme" \ -H "Content-Type: application/json" \ -d '{"first_name": "Jane", "last_name": "Doe", "domain": "acme.com"}' ``` ```json { "status": "valid", "email": "jane.doe@acme.com", "confirmed": true, "confidence": 95, "credits_charged": 1, "message": "Found and confirmed jane.doe@acme.com. 1 credit charged." } ``` Each call is charged by its own result. Do not repeat a lookup that found nothing; fix the name or the domain first. A full name works too: `{"name": "Dr. Jane Doe", "domain": "acme.com"}`. ## Many people [#many-people] Send up to 10,000 people as `rows` or as CSV text, with a spending limit: ```bash curl -X POST "https://app.argorant.com/api/v1/email-finder/jobs" \ -H "Authorization: Bearer $ARGORANT_API_KEY" -H "Idempotency-Key: q4-accounts-finder" \ -H "Content-Type: application/json" \ -d '{"name": "Q4 accounts", "max_credits": 100, "rows": [{"first_name": "Jane", "last_name": "Doe", "domain": "acme.com", "ref": "crm-1042"}]}' ``` The answer has the `job_id` and `maximum_charge`, the most the list can cost. Check the job about every 30 seconds with `GET /api/v1/email-finder/jobs/{job_id}` and read the rows from `.../results`, or all at once with `.../results?format=csv`. A list pauses instead of failing: | `paused_reason` | What happened | What to do | | ---------------------- | --------------------------------------------- | ------------------------------------------------ | | `spend_limit` | It reached your `max_credits` | Resume with a higher limit | | `insufficient_credits` | The account ran out of credits | Add credits, then resume | | `daily_limit` | The daily lookup limit was reached | Nothing; it goes on after midnight UTC | | `miss_rate` | Most lookups found nothing, so it slowed down | Nothing; it goes on. Check the names and domains | Resume with `POST .../resume` (optionally `{"max_credits": 150}`) and stop with `POST .../cancel`. Rows that were never looked up are never charged. CSV columns that work are `first_name` and `last_name` (or `name` or `full_name`), `domain` (or `company_domain` or `website`) and an optional `id` or `ref` that comes back with the result. ## Limits [#limits] 30 single lookups a minute and 2,000 lookups a day per account. An account whose lookups almost never find anything is slowed to 20 an hour for a while. It is never charged more. ## From the terminal [#from-the-terminal] ```bash npx argorant find "Jane Doe" --domain acme.com npx argorant find --file people.csv -o found.csv --max-credits 100 npx argorant find status npx argorant find pricing ``` ## From an AI assistant [#from-an-ai-assistant] The MCP server has `argorant_find_email` for one person and `argorant_find_emails` for a list (with a spending limit you must set), plus `argorant_find_emails_status` and `argorant_manage_find_emails`. See [Tools](/docs/agents/tools). # Connect a Google Workspace URL: https://docs.argorant.com/docs/guides/google-workspace One approval by the Workspace admin lists every mailbox and alias. Pick the ones that should send. No passwords and no sign-in per mailbox. ### Ask for the delegation values [#ask-for-the-delegation-values] ```bash curl -X POST "https://app.argorant.com/api/v1/inboxes/google-workspace" \ -H "Authorization: Bearer $ARGORANT_API_KEY" -H "Content-Type: application/json" \ -d '{"admin_email":"admin@yourdomain.com"}' ``` Until the admin approved it, the answer has `ok: false`, `mailboxes: null` and a `setup` block with `client_id`, `scopes_csv` and `delegation_url`, the values the admin needs. ### Grant it in Google Admin [#grant-it-in-google-admin] In Google Admin open **Security**, then **Access and data control**, **API controls**, **Domain-wide delegation** and **Add new**. Paste the client id and the scopes exactly as returned. An admin does this once per Workspace. ### List and connect [#list-and-connect] Call the same endpoint again. It now returns every mailbox and alias. Then send the addresses to connect, or an empty list for all of them: ```bash curl -X POST "https://app.argorant.com/api/v1/inboxes/google-workspace" \ -H "Authorization: Bearer $ARGORANT_API_KEY" -H "Content-Type: application/json" \ -d '{"admin_email":"admin@yourdomain.com","emails":["elena@yourdomain.com","marina@yourdomain.com"]}' # {"connected": [{"email": "elena@yourdomain.com", "health": "healthy"}]} ``` Connected mailboxes show up in `GET /api/v1/inboxes` with their health, daily limit and today's sends, and can send for any campaign. In the terminal the same is `npx argorant inboxes connect-google --admin admin@yourdomain.com --all`. # Guides URL: https://docs.argorant.com/docs/guides Step-by-step guides for the jobs people do most with Argorant. * [Your first call](/docs/guides/your-first-call): an API key and your first count. * [Find and email 200 people](/docs/guides/find-and-email-200-people): from a search to a running campaign. * [Find emails](/docs/guides/find-emails) and [check your own list](/docs/guides/verify-my-list). * [Find and export](/docs/guides/find-and-export): a search as a file. * [Campaigns from start to finish](/docs/guides/campaigns-end-to-end), [replies and the inbox](/docs/guides/replies-and-inbox). * Mailboxes: [Google Workspace](/docs/guides/google-workspace) and [other mailboxes](/docs/guides/smtp-mailboxes). * [Buy credits](/docs/guides/buy-credits), [webhooks](/docs/guides/webhooks) and [the command line](/docs/guides/cli). * [Integrations](/docs/integrations): HubSpot, Pipedrive, Google Sheets, lemlist, PlusVibe, Clay, Zapier, Make and n8n. # Answer replies URL: https://docs.argorant.com/docs/guides/replies-and-inbox Every reply from every campaign in one inbox. Read it, answer in the same thread, forward it, and mark it with a status such as interested, meeting booked or your own pipeline stage. ## See the new replies [#see-the-new-replies] ```bash curl "https://app.argorant.com/api/v1/inbox?folder=replies&limit=25" -H "Authorization: Bearer $ARGORANT_API_KEY" ``` `folder` is `all`, `replies`, `interested`, `not_interested`, `out_of_office`, `bounces` or `unsubscribes`. Narrow further with `campaign_id`, `classification` or a search word in `q`. Lists show the first 400 characters of each reply. Page with `cursor` and `next_cursor`. ## Read a conversation [#read-a-conversation] ```bash curl "https://app.argorant.com/api/v1/inbox/$THREAD" -H "Authorization: Bearer $ARGORANT_API_KEY" ``` `$THREAD` is the `id` from the list. You get the full text and the whole thread, oldest first: your emails, their replies, your answers and forwards. ## Answer in the same thread [#answer-in-the-same-thread] ```bash curl -X POST "https://app.argorant.com/api/v1/inbox/$THREAD/reply" \ -H "Authorization: Bearer $ARGORANT_API_KEY" -H "Idempotency-Key: reply-jane-1" \ -H "Content-Type: application/json" \ -d '{"body":"Thursday 10:00 works. I will send an invite."}' ``` The answer goes out at once, in the same thread, from the mailbox that got the reply. An agent should show the text to the user and wait for a yes. The `Idempotency-Key` makes sure a retry never sends it twice. ## Forward it to a colleague [#forward-it-to-a-colleague] ```bash curl -X POST "https://app.argorant.com/api/v1/inbox/$THREAD/forward" \ -H "Authorization: Bearer $ARGORANT_API_KEY" -H "Idempotency-Key: fwd-jane-1" \ -H "Content-Type: application/json" \ -d '{"to":["sales-lead@yourcompany.com"],"note":"Hot lead, please call her this week."}' ``` The forward carries the history and attachments. Within three minutes the conversation shows whether it was delivered. ## Mark it and track your pipeline [#mark-it-and-track-your-pipeline] Every workspace has five standard labels: `positive` (shown as Interested), `meeting_request`, `out_of_office`, `unsubscribe` and `neutral` (shown as Other). You can switch on `not_interested`, `question`, `referral`, `wrong_person` and `meeting_booked`. Add your own stages: ```bash curl -X POST "https://app.argorant.com/api/v1/reply-statuses" \ -H "Authorization: Bearer $ARGORANT_API_KEY" -H "Content-Type: application/json" \ -d '{"label":"Proposal sent","color":"purple"}' curl -X POST "https://app.argorant.com/api/v1/inbox/$THREAD/classify" \ -H "Authorization: Bearer $ARGORANT_API_KEY" -H "Content-Type: application/json" \ -d '{"classification":"proposal_sent"}' ``` `interested` is understood as `positive`. Rename, recolor, hide or show a stage with `PATCH /api/v1/reply-statuses/{key}`. Delete one of your own stages with `DELETE /api/v1/reply-statuses/{key}`; its conversations go back to neutral. ## Get told right away [#get-told-right-away] A [webhook](/docs/guides/webhooks) for `reply.positive` calls your server when someone is interested, so nobody waits for the next check. ## From the terminal [#from-the-terminal] ```bash npx argorant inbox list --folder replies npx argorant inbox read npx argorant inbox reply --body "Thursday works." npx argorant inbox classify meeting_booked ``` # Send people to your other tools URL: https://docs.argorant.com/docs/guides/send-to-other-tools Send a list, a campaign's people or an export into the sending tool you already use, in your own account there. Included from the Pro plan. You can keep sending from the tool you already use and let Argorant fill it. Argorant finds the people and checks every email. Your tool sends the emails. ## Connect your tool once [#connect-your-tool-once] 1. Open Settings, then Connected tools, in the Argorant app. 2. Pick your sending tool and paste its API key. You find the key in that tool's own settings. 3. The key is stored encrypted. It is only used to send the people you choose, into your own account. You can disconnect the tool there at any time. People you already sent stay where they are. ## Send from the app [#send-from-the-app] * **A list.** Open the list and choose **Push to** your tool. The list is exported first, so every email is checked and the export uses credits as usual. The people go to your tool as soon as the file is ready. You can close the window, it keeps going. * **A campaign.** Open the campaign, go to Leads and choose **Push to** your tool. You can send only the people who were not emailed yet. * **An export.** On the Exports page, choose **Push to your sequencer** and then **Send to another tool**. Pick the campaign inside your tool, then send. People who bounced, unsubscribed or are on your blocklist are never sent. Argorant never starts that campaign and never sends an email from there. You start it in your tool when you are ready. ## Send from the API [#send-from-the-api] | Call | What it does | | ----------------------------------------------------- | ----------------------------------------------------------------- | | `GET /api/v1/integrations` | Your connected tools, each with its id | | `GET /api/v1/integrations/{integration_id}/campaigns` | The campaigns inside one connected tool | | `POST /api/v1/integrations/{integration_id}/pushes` | Send a campaign's people or an export into one of those campaigns | | `GET /api/v1/integrations/pushes/{push_id}` | How the send stands | ```bash curl -X POST "https://app.argorant.com/api/v1/integrations/18/pushes" \ -H "Authorization: Bearer $ARGORANT_API_KEY" -H "Idempotency-Key: q4-cfos-1" \ -H "Content-Type: application/json" \ -d '{"campaign_id":"7f3a2c1e-9b4d-4e8a-a1c2-5d6e7f8a9b0c","target_campaign_id":"3356753","only_not_contacted":true}' ``` To send a list, export it first with `POST /api/v1/lists/{list_id}/export` and send that export with `"export_id"`. The send waits until the export is ready. With an export you can also pick which email results go, with `"results": ["valid", "catch_all"]`. ## From your AI assistant [#from-your-ai-assistant] The connector has three tools for this: `argorant_list_integrations`, `argorant_push_to_integration` and `argorant_integration_push_status`. The assistant asks for your yes before it sends anyone. It never asks for your tool's API key, because you connect the tool in the app. ## Limits [#limits] Up to 100,000 people go in one send. A send to your own tools is included from the Pro plan. An export costs credits when it runs, the same as any export. # Connect any mailbox (SMTP and IMAP) URL: https://docs.argorant.com/docs/guides/smtp-mailboxes Connect mailboxes from Zoho, Fastmail, Yahoo, iCloud, IONOS, your web host or any other provider with their server settings. Test the sign-in first, connect one at a time or many from a CSV file. Google and Microsoft mailboxes connect with their own sign-in (see [Connect a Google Workspace](/docs/guides/google-workspace), and Microsoft 365 in the app under Mailboxes). Every other provider connects with two sets of server settings. The sending server (SMTP) lets campaigns send from the mailbox. The server for reading replies (IMAP) brings the answers into your inbox in Argorant, so a reply stops the sequence for that person. Argorant signs in to both before it saves anything. A mailbox connects only when sending and reading replies both work. The password is stored encrypted and is never shown again, in the app, the API, the CLI or the connector. ## In the app [#in-the-app] Open **Mailboxes**, click **Add accounts**, then **Connect existing** and **Any other provider**. 1. Pick your provider from the list. It fills in the server names, ports and security for you. Pick **Other provider** when yours is not listed and copy the settings from your provider's help pages. 2. Enter the email address, the sender name people see and the password. 3. Click **Test connection**. You see one line for sending and one for reading replies, each with what worked or what to fix. 4. Click **Connect mailbox**. It shows up in the list right away with its daily limit and health. To connect many mailboxes at once, switch to **Many from a CSV file**, upload the file and check the result for each row. ## App passwords [#app-passwords] Many providers do not accept your normal password from other apps when two-step sign-in is on. Make an app password at the provider and use it instead. | Provider | Where to make an app password | | ----------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Zoho Mail | My Account, Security, App Passwords. Turn on IMAP access in Zoho Mail settings too. | | Fastmail | Settings, Privacy and Security, Manage app passwords. Always needed. | | Yahoo Mail | Account Info, Account Security, Generate app password. Always needed. | | iCloud Mail | account.apple.com, Sign-In and Security, App-Specific Passwords. Always needed. The username is your full iCloud address. | | Outlook.com and Hotmail | Microsoft often refuses passwords from other apps for these. Try an app password; if the test says the password is wrong, connect with the Microsoft sign-in instead. | ## Provider settings [#provider-settings] Pick a provider and these are filled in. The list in the app and `GET /api/v1/inboxes/smtp/presets` is always the current one. | Preset | Provider | Sending server | Server for reading replies | | --------------- | --------------------------------- | --------------------------------------- | ------------------------------- | | `zoho` | Zoho Mail (business domain) | smtppro.zoho.com, 587, STARTTLS | imappro.zoho.com, 993, SSL | | `zoho_eu` | Zoho Mail (EU data center) | smtppro.zoho.eu, 587, STARTTLS | imappro.zoho.eu, 993, SSL | | `zoho_personal` | Zoho Mail (personal or free plan) | smtp.zoho.com, 587, STARTTLS | imap.zoho.com, 993, SSL | | `fastmail` | Fastmail | smtp.fastmail.com, 587, STARTTLS | imap.fastmail.com, 993, SSL | | `godaddy` | GoDaddy Professional Email | smtpout.secureserver.net, 587, STARTTLS | imap.secureserver.net, 993, SSL | | `titan` | Titan Email | smtp.titan.email, 587, STARTTLS | imap.titan.email, 993, SSL | | `hostinger` | Hostinger Email | smtp.hostinger.com, 587, STARTTLS | imap.hostinger.com, 993, SSL | | `ionos` | IONOS (US) | smtp.ionos.com, 587, STARTTLS | imap.ionos.com, 993, SSL | | `ionos_de` | IONOS (Germany) | smtp.ionos.de, 587, STARTTLS | imap.ionos.de, 993, SSL | | `ionos_uk` | IONOS (UK) | smtp.ionos.co.uk, 587, STARTTLS | imap.ionos.co.uk, 993, SSL | | `namecheap` | Namecheap Private Email | mail.privateemail.com, 587, STARTTLS | mail.privateemail.com, 993, SSL | | `yahoo` | Yahoo Mail | smtp.mail.yahoo.com, 587, STARTTLS | imap.mail.yahoo.com, 993, SSL | | `icloud` | iCloud Mail | smtp.mail.me.com, 587, STARTTLS | imap.mail.me.com, 993, SSL | | `outlook` | Outlook.com or Hotmail | smtp-mail.outlook.com, 587, STARTTLS | outlook.office365.com, 993, SSL | | `other` | Other provider | you enter it | you enter it | Use port 587 for sending. If you enter 465, Argorant tries 587 for you and saves 587 when it works, and the test result then shows port 587 and STARTTLS for sending. The username for both servers is the email address unless you set another one. Reading replies uses the same username and password as sending unless you set others. Without a preset, security follows the port, so STARTTLS on 587 and 143 and SSL on 993. ## What the test result means [#what-the-test-result-means] | Result | What it means | What to do | | ------------------- | ---------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------- | | `signed_in` | The server accepted the sign-in. | Nothing. | | `wrong_password` | The server refused the username or password. | Check both. Use an app password if the provider asks for one, and check that IMAP access is turned on at the provider. | | `not_reachable` | The server did not answer, or there is no server with that name. | Check the server name and the port. | | `security_mismatch` | The secure connection did not work. | Try the other security setting. For sending, use port 587 with STARTTLS. | | `not_allowed` | The server name points to a private network. | Use your provider's public server name. | | `failed` | Something else went wrong. | Check the settings and try again, or contact support. | ## Many mailboxes from a CSV file [#many-mailboxes-from-a-csv-file] One row per mailbox. Each row needs `email`, `smtp_password` (or `password`) and either a `preset` or `smtp_host`, `smtp_port` and `imap_host`. Empty columns take the defaults above, and 25 emails a day. | Column | Example | | ----------------------------------------- | ---------------------------------------------------------------------- | | `email` | [anna@yourcompany.com](mailto:anna@yourcompany.com) | | `sender_name` | Anna Weber | | `preset` | zoho | | `smtp_host`, `smtp_port`, `smtp_security` | mail.yourcompany.com, 587, starttls | | `smtp_username`, `smtp_password` | [anna@yourcompany.com](mailto:anna@yourcompany.com), your app password | | `imap_host`, `imap_port`, `imap_security` | mail.yourcompany.com, 993, ssl | | `imap_username`, `imap_password` | only when they differ from sending | | `daily_limit` | 30 | ```csv email,sender_name,preset,smtp_password anna@yourcompany.com,Anna Weber,zoho,app-password-1 ben@yourcompany.com,Ben Hill,zoho,app-password-2 cara@othercompany.com,Cara Lane,,app-password-3 ``` The third row has no preset, so it also needs `smtp_host`, `smtp_port` and `imap_host` filled in, or it comes back as a row to fix. Every row gets its own result. Rows that connected stay connected when others fail, so fix the failed rows and upload only those again. ## Reconnect after a password change [#reconnect-after-a-password-change] When the provider refuses the password, the mailbox shows **Sign in again** in the Mailboxes list. If reading replies is refused three times in a row, the mailbox is marked disconnected and stays that way until you reconnect it. To reconnect, connect the same address again with the new password. In the app, click **Reconnect** on the mailbox, enter the new password and connect; the other settings are kept. With the API, the CLI or your AI assistant, connect the same address again, and it replaces the saved settings and password of that mailbox. ## From the API [#from-the-api] ```bash # Test first: nothing is saved curl -X POST "https://app.argorant.com/api/v1/inboxes/smtp/test" \ -H "Authorization: Bearer $ARGORANT_API_KEY" -H "Content-Type: application/json" \ -d '{"email":"anna@yourcompany.com","preset":"zoho","smtp_password":"app-password"}' # Connect one mailbox curl -X POST "https://app.argorant.com/api/v1/inboxes/smtp" \ -H "Authorization: Bearer $ARGORANT_API_KEY" -H "Content-Type: application/json" \ -d '{"email":"anna@yourcompany.com","display_name":"Anna Weber","preset":"zoho","smtp_password":"app-password"}' # Connect up to 25 at once curl -X POST "https://app.argorant.com/api/v1/inboxes/smtp/bulk" \ -H "Authorization: Bearer $ARGORANT_API_KEY" -H "Content-Type: application/json" \ -d '{"mailboxes":[{"email":"anna@yourcompany.com","preset":"zoho","smtp_password":"app-password-1"},{"email":"ben@yourcompany.com","preset":"zoho","smtp_password":"app-password-2"}]}' ``` A refused sign-in on connect answers `422` with the code `sign_in_failed` and the test result in `error.details.test`. The bulk route answers `200` with a result per row. A free trial connects up to 2 mailboxes. You can test 30 times and connect 30 times an hour, and connect up to 500 mailboxes an hour through the bulk route. ## From the terminal [#from-the-terminal] ```bash argorant inboxes presets argorant inboxes test-smtp --email anna@yourcompany.com --preset zoho argorant inboxes connect-smtp --email anna@yourcompany.com --preset zoho --name "Anna Weber" argorant inboxes connect-smtp --csv mailboxes.csv ``` The CLI never takes the password on the command line. It asks for it, or reads it from an environment variable you name with `--password-env NAME`, or from `ARGORANT_MAILBOX_PASSWORD`. See [CLI](/docs/guides/cli). ## From your AI assistant [#from-your-ai-assistant] With the Argorant connector, ask in plain words, for example "connect [anna@yourcompany.com](mailto:anna@yourcompany.com), it is a Zoho mailbox". The assistant uses `argorant_test_smtp_mailbox` to check the sign-in and `argorant_connect_smtp_mailbox` to connect one mailbox or up to 25. See [Tools](/docs/agents/tools). ## After connecting [#after-connecting] The mailbox sends like any other. Set its daily limit and warm-up under Mailboxes or with `PATCH /api/v1/inboxes/{email}`, and pick it as a sender in any campaign. Follow-ups go out in the same thread, replies land in your inbox in Argorant, and you answer them from there in the same thread. Replies that land in the junk or spam folder are read too, but only from people you emailed, so spam is ignored. # Verify my list URL: https://docs.argorant.com/docs/guides/verify-my-list Check the emails on a list you already have before you send to it. Get a free quote, say yes, and see which addresses are good. Half a credit per address. Sending to bad addresses hurts your mailboxes. Check a list first. You pay half a credit per address that needs a fresh check. Addresses checked recently are free, and the quote tells you the most it can cost before anything happens. ### Get a quote, free [#get-a-quote-free] Send the addresses, up to 5,000 rows and 1,000 different addresses per check: ```bash curl -X POST "https://app.argorant.com/api/v1/verifications/quote" \ -H "Authorization: Bearer $ARGORANT_API_KEY" -H "Content-Type: application/json" \ -d '{"emails": ["jane.doe@acme.com", "sam@globex.io", "info@initech.example"]}' ``` ```json { "quote_id": "4b1d2c3e4f5a6b7c8d9e0f1a2b3c4d5e", "unique_addresses": 3, "fresh_checks": 2, "duplicates_removed": 0, "invalid_rows": [], "maximum_charge": 1, "approval_required": true } ``` `maximum_charge` is the most the check costs, in credits. Repeated addresses and rows that are not an email are left out for free. ### Ask, then start [#ask-then-start] Show `maximum_charge` to the person who pays. After their yes: ```bash curl -X POST "https://app.argorant.com/api/v1/verifications" \ -H "Authorization: Bearer $ARGORANT_API_KEY" -H "Content-Type: application/json" \ -d '{"quote_id": "4b1d2c3e4f5a6b7c8d9e0f1a2b3c4d5e", "approved_maximum_charge": 1}' ``` The check checks exactly the list of the quote and never costs more than `approved_maximum_charge`. Starting the same quote again returns the same check. ### Read the results [#read-the-results] ```bash curl "https://app.argorant.com/api/v1/verifications/$RUN" -H "Authorization: Bearer $ARGORANT_API_KEY" ``` `summary` counts the results. `valid` is safe to send to. `invalid` will bounce. `catch_all` sits at a domain that accepts every address, so it cannot be confirmed. `risky` and `unknown` are better left out. The full list with every address is in the app at `results_url`. Your key needs the `argorant:verify_emails` scope; keys created in the app have it. From the terminal, `npx argorant verify --file my-list.csv -o checked.csv` does the same in one step. In Claude or ChatGPT, ask "Check the emails in this list before I send to them". # Webhooks URL: https://docs.argorant.com/docs/guides/webhooks Get a signed call to your server when a reply comes in, someone is interested, an email bounces, a list or an export is ready. Included from the Pro plan. ## Events [#events] | Event | When | What `data` holds | | ------------------------ | ---------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------ | | `reply.received` | A person replied to one of your campaigns. Out-of-office and other automatic replies are left out | `classification`, `lead_email`, `campaign_id`, `subject`, `snippet` | | `reply.positive` | A reply was labelled interested | The same as above | | `email.bounced` | A campaign email bounced | `lead_email`, `campaign_id`, `subject` | | `email.unsubscribed` | Someone asked to stop, complained, or used the opt-out link | `classification`, `lead_email`, `campaign_id`, `subject`, `snippet`, and `source` for the opt-out link | | `campaign.paused` | Sending paused: the month's campaign emails of your plan are used up, or the campaign paused itself (for example too many bounces) | `campaign_id`, `campaign_name`, `reason`, and `campaign_emails` (plan) or `message`, `metrics`, `url` (auto-pause) | | `campaign.resumed` | The month started again or the plan grew, so sending goes on | `campaign_id`, `campaign_name`, `reason`, `campaign_emails` | | `export.ready` | An export finished | `job_id`, `status`, `total_rows`, `verified_rows`, `status_url`, `download_url` | | `list.ready` | A list finished filling, also after you added more people | `list_id`, `list_name`, `job_id`, `status`, `total_items`, `note`, `status_url` | | `verification.completed` | A single email check with an API key finished | `email`, `status`, `deliverable`, `is_role_based`, `is_free`, `is_disposable` | | `segment.new_matches` | A saved list has new people who match its filters | `list_id`, `list_name`, `previous_total`, `current_total`, `new_matches` | Campaign events go to the webhooks of the workspace owner and of every active team member, so each person can point them at their own tools. Exports, lists and checks go to the webhooks of the person who started them. ## Create a webhook [#create-a-webhook] ```bash curl -X POST "https://app.argorant.com/api/v1/webhooks" \ -H "Authorization: Bearer $ARGORANT_API_KEY" -H "Idempotency-Key: hook-crm-1" \ -H "Content-Type: application/json" \ -d '{"url":"https://example.com/hooks/argorant","events":["reply.positive","email.bounced","export.ready"]}' ``` The address must be a public `https://` address. The answer holds the signing `secret`. It is shown only once, so store it now. Each account can have up to 10 webhooks, switched off ones included. | Call | What it does | | -------------------------------------- | --------------------------------------------------------------------- | | `GET /api/v1/webhooks` | Your webhooks and every event you can choose | | `PATCH /api/v1/webhooks/{id}` | Change the URL or the events, or switch it off with `"active": false` | | `DELETE /api/v1/webhooks/{id}` | Remove it | | `POST /api/v1/webhooks/{id}/test` | Send one signed test call | | `GET /api/v1/webhooks/{id}/deliveries` | Recent calls with their result and the next try | ## What your server receives [#what-your-server-receives] ```http POST /hooks/argorant Content-Type: application/json User-Agent: Argorant-Webhooks/1.0 X-Argorant-Event: reply.positive X-Argorant-Delivery: 8841 X-Argorant-Signature: sha256=5d41402abc4b2a76b9719d911017c592... {"event": "reply.positive", "delivery_id": "8841", "created_at": "2026-10-07T09:14:03+00:00", "data": {"classification": "positive", "lead_email": "jane.doe@acme.com", "campaign_id": "7f3a2c1e-9b4d-4e8a-a1c2-5d6e7f8a9b0c", "subject": "Re: Quick question", "snippet": "Happy to talk..."}} ``` Answer with any 2xx status within a few seconds. Do the slow work after you answered. Redirects are not followed, so use the final address. ## Check the signature [#check-the-signature] The signature is the HMAC-SHA256 of the raw body with your secret. Compare it before you trust the call. Use the body bytes exactly as they arrived, before any JSON parsing. ```python import hmac, hashlib def is_from_argorant(secret: str, raw_body: bytes, signature_header: str) -> bool: expected = "sha256=" + hmac.new(secret.encode(), raw_body, hashlib.sha256).hexdigest() return hmac.compare_digest(expected, signature_header) ``` ```js const crypto = require("crypto"); function isFromArgorant(secret, rawBody, signatureHeader) { const expected = Buffer.from("sha256=" + crypto.createHmac("sha256", secret).update(rawBody).digest("hex")); const given = Buffer.from(signatureHeader || ""); return given.length === expected.length && crypto.timingSafeEqual(expected, given); } ``` The signed body holds `delivery_id` and `created_at`, so neither can be changed without breaking the signature. Keep the delivery ids you handled and skip one you have seen before. That makes a replayed call harmless. ## When your server is down [#when-your-server-is-down] A call that fails is tried again after 1 minute, 5 minutes, 30 minutes, 2 hours and 6 hours, so up to 6 times. `X-Argorant-Delivery` stays the same for every try of one event, so use it to skip events you already handled. After 50 failed calls in a row the webhook is switched off; switch it on again with `PATCH` and `"active": true`. # Your first call URL: https://docs.argorant.com/docs/guides/your-first-call The quickstart. With one API key you count a market, look at the people, reveal a few, save them as a list and prepare a campaign. Counting and looking are free. You need an API key. Create one at [app.argorant.com/profile](https://app.argorant.com/profile) under API keys. It starts with `ag_live_` and is shown once. Every new account gets a 14-day trial with 100 credits and 300 campaign emails, without a card. ```bash export ARGORANT_API_KEY=ag_live_... ``` ### Check the key [#check-the-key] ```bash curl "https://app.argorant.com/api/v1/account" -H "Authorization: Bearer $ARGORANT_API_KEY" ``` You see your plan, your credits, how many requests a minute the key may send and what is left of today's limits. ### Count a market, free [#count-a-market-free] ```bash curl -G "https://app.argorant.com/api/v1/people/count" \ -H "Authorization: Bearer $ARGORANT_API_KEY" \ --data-urlencode "title=CFO" --data-urlencode "country=Germany" --data-urlencode "employee_range=51-200" # {"count": 4210} ``` Not sure which words to use? `GET /api/v1/lookups/industries?q=soft` and `GET /api/v1/lookups/titles?q=head of` give the exact names with how many people carry each. ### Look at who matches, free [#look-at-who-matches-free] ```bash curl -G "https://app.argorant.com/api/v1/people/search" \ -H "Authorization: Bearer $ARGORANT_API_KEY" \ --data-urlencode "title=CFO" --data-urlencode "country=Germany" --data-urlencode "employee_range=51-200" --data-urlencode "limit=10" ``` Each row shows the role, the company and the place, with the name cut to initials and no contact details. Every row has a `record_id`. ### Reveal a few people [#reveal-a-few-people] This spends credits, so in an app or an agent, show the price and ask first. ```bash curl -X POST "https://app.argorant.com/api/v1/people/reveal" \ -H "Authorization: Bearer $ARGORANT_API_KEY" \ -H "Idempotency-Key: first-reveal-1" \ -H "Content-Type: application/json" \ -d '{"title":"CFO","country":"Germany","employee_range":"51-200","limit":5}' ``` Every email is checked right before you get it. You pay 1 credit per person whose email passes and nothing for the rest. `credits_charged` says what it cost. ### Save the search as a list [#save-the-search-as-a-list] ```bash curl -X POST "https://app.argorant.com/api/v1/lists" \ -H "Authorization: Bearer $ARGORANT_API_KEY" \ -H "Idempotency-Key: first-list-1" \ -H "Content-Type: application/json" \ -d '{"name":"CFOs Germany 51-200","filters":{"title":"CFO","country":"Germany","employee_range":"51-200"}}' ``` Saving is free and reveals nobody. Keep the `list_id`. ### Prepare a campaign [#prepare-a-campaign] ```bash curl -X POST "https://app.argorant.com/api/v1/campaigns" \ -H "Authorization: Bearer $ARGORANT_API_KEY" -H "Idempotency-Key: first-campaign-1" \ -H "Content-Type: application/json" -d '{"name":"CFOs Germany Q4","daily_limit":40}' ``` The campaign starts as a draft. Nothing is sent until you launch it. [Find and email 200 people](/docs/guides/find-and-email-200-people) shows the rest: the emails, the people, the mailboxes and the launch. The same steps in the terminal: `npx argorant count`, `npx argorant search`, `npx argorant reveal`, `npx argorant list create`, `npx argorant campaigns create`. In Claude or ChatGPT, connect `https://mcp.argorant.com/mcp` and ask in plain words. # Clay URL: https://docs.argorant.com/docs/integrations/clay Use Argorant from Clay with your API key: count people, look at them, find emails and run exports. Add Argorant to a Clay table as an HTTP API column, so every row gets an email or more details from Argorant. ## Before you start [#before-you-start] Create an API key in Argorant under **Settings**, **API keys**. Every request sends it as a header: ```text Authorization: Bearer YOUR_API_KEY ``` All addresses start with `https://app.argorant.com`. See [Authentication](/docs/getting-started/authentication) for limits and errors. ## Set up the column [#set-up-the-column] 1. In your Clay table add a column and choose **HTTP API**. 2. Method `POST`, URL `https://app.argorant.com/api/v1/email-finder/find` to find an email, or `https://app.argorant.com/api/v1/enrich` to fill in details. 3. Add the header `Authorization` with `Bearer YOUR_API_KEY`. 4. In the body, map the columns of your table, for example first name, last name and company website. 5. Run the column on a few rows first and check the result before running it on the whole table. ## Calls you will use most [#calls-you-will-use-most] | What | Request | | --------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Count people for a search (free) | `GET /api/v1/people/count` ([reference](/docs/reference/people/count-people)) | | Look at matching people (free, emails hidden) | `GET /api/v1/people/search` ([reference](/docs/reference/people/search-people)) | | Get emails for chosen people | `POST /api/v1/people/reveal` ([reference](/docs/reference/people/reveal-people)) | | Find one person's email from name and company | `POST /api/v1/email-finder/find` | | Fill in a person or company you already have | `POST /api/v1/enrich` ([reference](/docs/reference/enrich/enrich)) | | Export a whole search as a file | `POST /api/v1/exports`, then `GET /api/v1/exports/{job_id}` until it is done, then `GET /api/v1/exports/{job_id}/download` ([reference](/docs/reference/exports/create-export)) | Counting and looking are free. Credits are used for emails you get, phone numbers and exports, the same as in the app. # Google Sheets URL: https://docs.argorant.com/docs/integrations/google-sheets Turn any finished export into a new Google Sheet with one click. ### Connect your Google account [#connect-your-google-account] In Argorant open **Settings**, then **Connected tools**, and click **Connect Google Sheets**. Argorant can only see and edit the spreadsheets it creates for you, never the rest of your Drive. You can also connect the first time you send an export. ### Send an export to a sheet [#send-an-export-to-a-sheet] Open **Exports**. Every finished export has a **Send to Google Sheets** button next to Download. Pick which email results to include. A new spreadsheet opens in a new tab when it is ready. ## Good to know [#good-to-know] * The sheet has the same columns as the CSV file: email, first name, last name, company, title, location, phone and LinkedIn. * Up to 100,000 rows per sheet. * Sending the same export again creates a new spreadsheet. Nothing is overwritten. * Sending to Google Sheets costs no credits. If you disconnect, your existing sheets stay in your Drive. # HubSpot URL: https://docs.argorant.com/docs/integrations/hubspot Connect HubSpot once, then send any finished export into it as contacts. ### Connect HubSpot [#connect-hubspot] In Argorant open **Settings**, then **Connected tools**, and click **Connect HubSpot**. HubSpot asks you to approve access to your contacts. After you approve, you come straight back to Argorant. One HubSpot account per workspace; connecting again replaces the old connection. ### Export the people you want [#export-the-people-you-want] Find the people in Search, select them or save them as a list, and start an export. Every email is checked when the export runs. ### Send the export to HubSpot [#send-the-export-to-hubspot] Back in **Settings**, **Connected tools**, your recent exports are listed under the connected tools. Click **Push to HubSpot** next to the export and confirm. ## What arrives in HubSpot [#what-arrives-in-hubspot] Each person becomes a contact, matched by email, so a person who is already in HubSpot is updated instead of added twice. First name, last name, job title, company, phone, city, state, country and the LinkedIn address are filled in where Argorant has them. ## Good to know [#good-to-know] * Sending to HubSpot costs no credits. * You can disconnect at any time in the same place. Contacts already in HubSpot stay there. # Integrations URL: https://docs.argorant.com/docs/integrations Send the people you find in Argorant to the tools you already use, or call Argorant from your own automations. There are two kinds of integrations. **Connected tools.** You connect them once in Argorant under **Settings**, **Connected tools**. After that every finished export can be sent to them with one click. * [HubSpot](/docs/integrations/hubspot): exports go in as contacts. * [Pipedrive](/docs/integrations/pipedrive): exports go in as persons, linked to their organizations. * [Google Sheets](/docs/integrations/google-sheets): an export becomes a new spreadsheet. * [lemlist](/docs/integrations/lemlist) and [PlusVibe](/docs/integrations/plusvibe): exports go into one of your campaigns there. * [Your own sending tool](/docs/guides/send-to-other-tools): lists, campaign people and exports go into one of your campaigns there, connected with that tool's API key. **Automation tools.** They call the Argorant API with your API key. Nothing to connect inside Argorant. * [Clay](/docs/integrations/clay), [Zapier](/docs/integrations/zapier), [Make](/docs/integrations/make) and [n8n](/docs/integrations/n8n). AI assistants such as Claude and ChatGPT connect through [Agents and MCP](/docs/agents). Sending to a connected tool costs no credits. Credits are only used when the export itself runs. # lemlist URL: https://docs.argorant.com/docs/integrations/lemlist Connect lemlist with an API key, then send any finished export into one of your lemlist campaigns. ### Create an API key in lemlist [#create-an-api-key-in-lemlist] In lemlist open **Settings**, then **Integrations**, then **API**, and create an API key. ### Connect it in Argorant [#connect-it-in-argorant] In Argorant open **Settings**, then **Connected tools**, click **Connect lemlist** and paste the key. Argorant checks the key right away and keeps it encrypted. You can disconnect at any time. ### Export the people you want [#export-the-people-you-want] Find the people in Search, select them or save them as a list, and start an export. Every email is checked when the export runs. ### Send the export to a campaign [#send-the-export-to-a-campaign] In **Settings**, **Connected tools**, click **Push to lemlist** next to the export, pick the campaign and confirm. ## Good to know [#good-to-know] * Argorant only adds people to the campaign you pick. It never starts the campaign, changes its schedule or its emails, or sends anything. * People who are already in the campaign are skipped, so sending an export twice does not add anyone twice. * Only people whose email is valid are sent. Unknown, catch-all and invalid addresses stay out. * Sending to lemlist costs no credits. # Make URL: https://docs.argorant.com/docs/integrations/make Use Argorant from Make with your API key: count people, look at them, find emails and run exports. Call Argorant from a Make scenario with the HTTP module. ## Before you start [#before-you-start] Create an API key in Argorant under **Settings**, **API keys**. Every request sends it as a header: ```text Authorization: Bearer YOUR_API_KEY ``` All addresses start with `https://app.argorant.com`. See [Authentication](/docs/getting-started/authentication) for limits and errors. ## Set up the module [#set-up-the-module] 1. In your scenario add the **HTTP** module **Make a request**. 2. Paste the address from the table below and pick the method. 3. Add the header `Authorization` with `Bearer YOUR_API_KEY`. 4. For a POST, set the body type to JSON and add your filters. For exports: start the export, then use a **Repeater** with a short **Sleep** and a second HTTP module that checks the export until it is done. Then download the file with a third request. A [webhook](/docs/guides/webhooks) to a Make **Custom webhook** saves the waiting. ## Calls you will use most [#calls-you-will-use-most] | What | Request | | --------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Count people for a search (free) | `GET /api/v1/people/count` ([reference](/docs/reference/people/count-people)) | | Look at matching people (free, emails hidden) | `GET /api/v1/people/search` ([reference](/docs/reference/people/search-people)) | | Get emails for chosen people | `POST /api/v1/people/reveal` ([reference](/docs/reference/people/reveal-people)) | | Find one person's email from name and company | `POST /api/v1/email-finder/find` | | Fill in a person or company you already have | `POST /api/v1/enrich` ([reference](/docs/reference/enrich/enrich)) | | Export a whole search as a file | `POST /api/v1/exports`, then `GET /api/v1/exports/{job_id}` until it is done, then `GET /api/v1/exports/{job_id}/download` ([reference](/docs/reference/exports/create-export)) | Counting and looking are free. Credits are used for emails you get, phone numbers and exports, the same as in the app. # n8n URL: https://docs.argorant.com/docs/integrations/n8n Use Argorant from n8n with your API key: count people, look at them, find emails and run exports. Call Argorant from an n8n workflow with the HTTP Request node, also as a tool for an AI agent. ## Before you start [#before-you-start] Create an API key in Argorant under **Settings**, **API keys**. Every request sends it as a header: ```text Authorization: Bearer YOUR_API_KEY ``` All addresses start with `https://app.argorant.com`. See [Authentication](/docs/getting-started/authentication) for limits and errors. ## Set up the node [#set-up-the-node] 1. Add an **HTTP Request** node. 2. Pick the method and paste the address from the table below. 3. Under authentication choose **Generic credential type**, then **Header Auth**, with the name `Authorization` and the value `Bearer YOUR_API_KEY`. 4. Send your filters as query parameters (GET) or as a JSON body (POST). An **AI Agent** node can use the same HTTP Request node as a tool, so the agent can count and look up people on its own. For a full assistant, connect the agent through [Agents and MCP](/docs/agents) instead. ## Calls you will use most [#calls-you-will-use-most] | What | Request | | --------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Count people for a search (free) | `GET /api/v1/people/count` ([reference](/docs/reference/people/count-people)) | | Look at matching people (free, emails hidden) | `GET /api/v1/people/search` ([reference](/docs/reference/people/search-people)) | | Get emails for chosen people | `POST /api/v1/people/reveal` ([reference](/docs/reference/people/reveal-people)) | | Find one person's email from name and company | `POST /api/v1/email-finder/find` | | Fill in a person or company you already have | `POST /api/v1/enrich` ([reference](/docs/reference/enrich/enrich)) | | Export a whole search as a file | `POST /api/v1/exports`, then `GET /api/v1/exports/{job_id}` until it is done, then `GET /api/v1/exports/{job_id}/download` ([reference](/docs/reference/exports/create-export)) | Counting and looking are free. Credits are used for emails you get, phone numbers and exports, the same as in the app. # Pipedrive URL: https://docs.argorant.com/docs/integrations/pipedrive Connect Pipedrive once, then send any finished export into it as persons linked to their organizations. ### Connect Pipedrive [#connect-pipedrive] In Argorant open **Settings**, then **Connected tools**, and click **Connect Pipedrive**. Approve access in Pipedrive and you come straight back. Connecting again replaces the old connection. ### Export the people you want [#export-the-people-you-want] Find the people in Search, select them or save them as a list, and start an export. Every email is checked when the export runs. ### Send the export to Pipedrive [#send-the-export-to-pipedrive] In **Settings**, **Connected tools**, click **Push to Pipedrive** next to the export and confirm. ## What arrives in Pipedrive [#what-arrives-in-pipedrive] Each person becomes a person in Pipedrive with name, work email, phone and job title. Their company becomes an organization: an organization with the same name is reused, a missing one is created. A person whose email is already in Pipedrive is skipped, never added twice. Sending to Pipedrive costs no credits. # PlusVibe URL: https://docs.argorant.com/docs/integrations/plusvibe Connect PlusVibe with an API key, then send any finished export into one of your PlusVibe campaigns. ### Create an API key in PlusVibe [#create-an-api-key-in-plusvibe] In PlusVibe open **Settings**, then **API access**, and create an API key. PlusVibe offers API keys on its Business plan. ### Connect it in Argorant [#connect-it-in-argorant] In Argorant open **Settings**, then **Connected tools**, click **Connect PlusVibe** and paste the key. Argorant checks the key right away and keeps it encrypted. You can disconnect at any time. ### Export the people you want [#export-the-people-you-want] Find the people in Search, select them or save them as a list, and start an export. Every email is checked when the export runs. ### Send the export to a campaign [#send-the-export-to-a-campaign] In **Settings**, **Connected tools**, click **Push to PlusVibe** next to the export, pick the campaign and confirm. ## Good to know [#good-to-know] * Argorant only adds people to the campaign you pick. It never starts the campaign, changes its schedule or its emails, or sends anything. * People who are already in the campaign are skipped, so sending an export twice does not add anyone twice. * Only people whose email is valid are sent. Unknown, catch-all and invalid addresses stay out. * If your key reaches several PlusVibe workspaces, Argorant asks which one to use. * Sending to PlusVibe costs no credits. # Zapier URL: https://docs.argorant.com/docs/integrations/zapier Use Argorant from Zapier with your API key: count people, look at them, find emails and run exports. Call Argorant from any Zap with a Webhooks step: counts, searches, emails and exports, no code. ## Before you start [#before-you-start] Create an API key in Argorant under **Settings**, **API keys**. Every request sends it as a header: ```text Authorization: Bearer YOUR_API_KEY ``` All addresses start with `https://app.argorant.com`. See [Authentication](/docs/getting-started/authentication) for limits and errors. ## Set up the step [#set-up-the-step] 1. In your Zap add the step **Webhooks by Zapier** and choose **Custom Request**. 2. Pick the method and paste the address from the table below, for example `GET https://app.argorant.com/api/v1/people/count`. 3. Under **Headers** add `Authorization` with `Bearer YOUR_API_KEY`. 4. Put your filters in the query (for a GET) or in the data as JSON (for a POST), then test the step. For exports, start the export in one step, then wait and check it in a second step until it says done. To be told when an export is ready instead, use a [webhook](/docs/guides/webhooks) pointed at a **Catch Hook** trigger. ## Calls you will use most [#calls-you-will-use-most] | What | Request | | --------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Count people for a search (free) | `GET /api/v1/people/count` ([reference](/docs/reference/people/count-people)) | | Look at matching people (free, emails hidden) | `GET /api/v1/people/search` ([reference](/docs/reference/people/search-people)) | | Get emails for chosen people | `POST /api/v1/people/reveal` ([reference](/docs/reference/people/reveal-people)) | | Find one person's email from name and company | `POST /api/v1/email-finder/find` | | Fill in a person or company you already have | `POST /api/v1/enrich` ([reference](/docs/reference/enrich/enrich)) | | Export a whole search as a file | `POST /api/v1/exports`, then `GET /api/v1/exports/{job_id}` until it is done, then `GET /api/v1/exports/{job_id}/download` ([reference](/docs/reference/exports/create-export)) | Counting and looking are free. Credits are used for emails you get, phone numbers and exports, the same as in the app. # API reference URL: https://docs.argorant.com/docs/reference Every endpoint of the Argorant API with parameters, examples and a live playground. Argorant is a complete B2B outreach platform that a script or an AI agent can run from start to finish. Find the companies and people that fit your offer among 630.7M+ contacts in 202 countries. Get their work emails, checked right before you receive them, and their phone numbers. Find one person's email from a name and a company domain. Check the emails on your own lists. Write a campaign with a personal line for every contact, send it from your own Google Workspace or Microsoft 365 mailboxes or from new mailboxes we set up on new domains for you, and answer the replies in the same thread. Authenticate with `Authorization: Bearer `. Every error has the same shape, `{"error": {"code", "message", "details"}, "request_id"}`, with a stable code ([all codes](/docs/getting-started/errors-and-limits)). Lists take `limit` and `cursor` and answer with `total`, `next_cursor` and `has_more`. Every write accepts an `Idempotency-Key`. Each page shows what the call costs and whether it spends credits, sends email or charges money. ## Groups [#groups] ## Base URL [#base-url] | Environment | Base URL | | ----------- | -------------------------- | | Production | `https://app.argorant.com` | The OpenAPI document is published at [/openapi.json](/openapi.json) for Postman, code generators and agents.