One platform, three drivers.
Coil is a single workspace for leads, scrapes, recipes, and automations, with three interfaces attached to the same primitives. The dashboard serves people who think in screens. The authenticated API is the product boundary for software operators. The JSON CLI gives scripts and approved agents a structured client, with capability manifests so they do not have to infer actions from the UI.
On this page.
1. One platform, three drivers.
Most outreach tools pick a surface and optimize for it. Apollo and Clay are dashboard products with API endpoints bolted on the side. SDR seats are dashboard products with a human in the loop and no API at all. The CLI category tends to ship a thin wrapper around a REST API that nobody dogfoods. The result is the same in each case: the surface that came second is a second-class citizen, and the agent or operator using it spends their time working around the gap.
Coil is built the other way around. The product is a single data surface plus a single set of actions on that surface. The data lives in Postgres with strict org-level partitioning. The actions live behind authenticated HTTP routes that accept either a Clerk session token or a Coil organization API key. On top of those routes we ship three drivers, and the drivers are siblings, not a hierarchy.
The first driver is the dashboard. It is a Next.js app that talks to the same authenticated API routes. Humans who think in screens use the dashboard to build prospect lists, queue scrapes, review leads, and configure automations. The dashboard is where you go when you want to see shape and feel of the data without a JSON viewer in the way.
The second driver is the coil CLI. It is distributed as a proprietary, versioned package with an explicit npm publication check before installing. The CLI authenticates with the same browser session or Coil organization API key, calls the same routes, and returns the same data. Every command supports a --json flag for structured output and a default human-readable mode for terminal use. The CLI is the driver for operators who live in shells, for one-off automation, and for scripts that run on a schedule.
The third driver is the authenticated Agent API. Organization API keys identify machine actors, while the same route and service boundaries enforce tenant scope, roles, and confirmations. Capability manifests describe CLI actions, parameters, return shapes, and examples. A Codex skill packages operating guidance, but it is not an MCP server.
Three drivers, one platform. The choice between them is taste plus context, not capability. If you are building a list at 2pm on a Tuesday with a coffee in hand, the dashboard is faster. If you are running a nightly enrichment loop from a CI job, the CLI is faster. If an approved agent is operating the workflow, it uses the API or JSON CLI with its own machine identity. The data and audit trail remain in the same workspace.
2. Data and actions are the same primitives.
The methodology only works if the drivers are operating on the same primitives. They do. Coil has four domain objects you interact with day to day. A scrape is a list-building job: a set of filters plus the rows it produced. A lead is a single row inside a scrape, with contact and firmographic data. A recipe is a typed, linear workflow that runs providers like enrichment, verification, and message generation in sequence. An automation is a webhook configuration that ships rows to external endpoints under an org-level egress policy. Routine operations use shared services; the repository parity matrix records deliberate role gates and dashboard-first gaps.
That is not a marketing claim. The CLI surface lives in packages/cli/src/commands/ and the matching capability manifests live in packages/cli/skills/. If you want to know whether a particular action is reachable from a particular driver, the answer is in the repository. There are skills for scrapes, leads, recipes, automations, recipe-templates, smartlead, members, integrations, actor-lab, auth, config, and the core operator surfaces. Every one of them has a JSON description returned by coil agent-context --json.
Honest hedge. Parity is incomplete today, and the gaps are not random. The CLI and capability manifests cover the routine agent workflows, while some actor-lab and organization-administration surfaces remain dashboard-first or human-admin only. Conversely, a handful of human-oriented operator views, including parts of the actor lab admin review interface, are dashboard-first and expose only a read API to other drivers. The repository is the source of truth on what is shipped today.
Some actions are deliberately not available to machine API keys. Publishing recipes or automations, mutating provider credentials, and selected destructive or policy operations require a human organization admin. Machine preferences remain scoped to the machine actor rather than borrowing a human's layout. These boundaries are documented in the parity matrix and enforced by route-level role checks.
The reason for spelling this out is that the alternative is worse. Plenty of products advertise an API and then quietly ship dashboard-only features, or ship an API-only feature that the dashboard cannot read. Coil treats every surface as a first-class citizen because the cost of the alternative is a category of paper cut that an operator or an agent runs into on day two.
3. Every skill is a manifest.
A Coil capability manifest is a JSON document that tells an agent what a CLI action does, what arguments it accepts, what shape it returns, and how to call it correctly. The CLI returns these manifests through runtime discovery. They are standalone contracts and do not imply an MCP transport.
Here is a short slice of the actual scrapes skill manifest as it lives in packages/cli/skills/scrapes.json:
{
"name": "scrapes",
"description": "Create, list, get, and delete lead scraping jobs. Supports prospect (filter-based) and sales-nav (URL-based) types.",
"commands": [
{
"name": "scrapes create",
"description": "Create a new scrape. Use --type prospect for filter-based or --type sales-nav for URL-based.",
"params": [
{ "name": "--type", "type": "string", "required": true,
"description": "Scrape type: 'prospect' or 'sales-nav'" },
{ "name": "--titles", "type": "string", "required": false,
"description": "Comma-separated job titles (prospect only)" },
{ "name": "--locations", "type": "string", "required": false,
"description": "Comma-separated locations (prospect only)" },
{ "name": "--sizes", "type": "string", "required": false,
"description": "Comma-separated company sizes (prospect only)" },
{ "name": "--fetch-count", "type": "number", "required": false,
"description": "Number of records to scrape" }
],
"output": {
"type": "object",
"properties": {
"id": { "type": "string" },
"name": { "type": "string" },
"status": { "type": "string" },
"created_at": { "type": "string", "format": "date-time" }
}
},
"examples": [
"coil scrapes create --type prospect --name 'CEOs in NYC' --titles 'CEO,CTO' --locations 'New York' --sizes '51-200' --fetch-count 100 --max-provider-spend-usd 2.00 --confirm-provider-spend"
]
}
]
}That snippet is load-bearing. It is part of what coil agent-context --jsonreturns for runtime discovery. The agent learns that scrapes create exists, that the --type flag is required, that --titles is optional and comma-separated, and that the response will carry an id, a status, and a created_at timestamp. When the user says find me a hundred CEOs in New York, the agent has everything it needs to construct a valid call and to handle the response.
The reason the manifest lives in the repository, instead of being generated at runtime, is that the manifest is reviewable. Every change to a Coil action that affects its interface is a change to the manifest, which is a change in a pull request, which is a thing a human can read before it ships. That property matters when the consumer of the change is an autonomous agent that will keep calling the tool at 3am. Drift between docs and reality is the kind of bug that costs an agent hours and a human a debugging session, so we make drift hard.
The same skill manifests are checked into the repository for every surface, including the more technical ones. The auth skill describes how to authenticate as a human or as an agent. The recipes skill describes the four lifecycle stages (create, validate, publish, run). The automations skill describes the policy validation, the human admin requirement for publish, and the run endpoint. Every skill is a manifest. The manifest is the contract. The contract is reviewable.
4. Concrete example for each driver.
Three short walkthroughs of the same job: build a prospect list of operators at small US fintechs and queue it. The action is the same in every case. The driver is the difference.
Driver one: the dashboard.
You sign in, hit the new scrape button, and pick prospect mode. The form gives you autocompletes for titles, locations, company sizes, and industries. You enter VP Operations and COO, set the location to United States, set company size to 51 to 200 and 201 to 500, set the industry filter to include Financial Services, set the lead count to 200, and submit. The dashboard posts to /api/scrapes, the service layer writes the row to Postgres with your org ID and your user ID, and the recipe worker picks the job up. You land on the scrapes table with a queued row. When the rows arrive, the leads table opens with column filters you can save as preferences. See /product/prospect for the deep dive.
Driver two: the CLI.
You authenticate once with coil auth login in your browser, or you set COIL_API_KEY=ak_... if you are running unattended. Then you queue the same job with one command. The actual command signature, copied verbatim from the examples block in the scrapes skill manifest, looks like this:
$ coil scrapes create \
--type prospect \
--name "Fintech operators" \
--titles "COO,VP Operations" \
--locations "United States" \
--sizes "51-200,201-500" \
--industries-include "Financial Services" \
--fetch-count 200 \
--max-provider-spend-usd 2.00 \
--confirm-provider-spend \
--json
{
"id": "scrape_abc123",
"name": "Fintech operators",
"status": "queued",
"created_at": "2026-05-20T14:22:10.118Z"
}The shape of the response is the shape advertised in the manifest: id, name, status, created_at. From there you can poll with coil scrapes get scrape_abc123 --json to check status, list the rows with coil leads list scrape_abc123 --json, or pipe a CSV out with coil leads export scrape_abc123 --output fintech.csv. Supported operational commands expose structured JSON, while individual command help documents its pagination, confirmation, and dry-run options. Those controls are command-specific; the CLI does not claim that every mutation has the same flags.
When the same job needs to run on a schedule, the CLI is the natural driver. You wrap the command in a cron entry or a CI workflow, store the API key in the secret manager, and let it run. Mutating API paths with audit coverage record the actor with actor.type = machine and the key ID, so the difference between a human click and a scheduled call is visible after the fact.
Driver three: the authenticated Agent API.
An approved agent receives a Coil organization API key through its secret manager and starts with coil agent-context --json. The returned contracts describe supported actions and explicit approval requirements. The agent can then construct a valid command, report durable queued state accurately, and hand off human-admin steps. The CLI calls the same organization-scoped routes and services as the dashboard.
The agent is not guessing. It read the manifest, it knows that --type must be prospect or sales-nav, it knows that --titles is comma-separated and prospect-only, and it knows that the response shape carries an id it can refer to later. If you follow up with show me the first ten rows when it is ready, the agent calls leads list with the saved scrape ID and renders the rows in chat. The agent never had to be told how to do this. The manifest taught it.
5. Where the methodology bites.
The methodology is a commitment, not a finished state. There are places where it bites today, and being upfront about them is part of the methodology, not a footnote.
Parity is incomplete. The CLI and capability manifests cover routine agent workflows, but parts of the actor lab review queue and organization administration remain dashboard-first or human-admin only. The dashboard ships a few operator interfaces, including the actor lab admin review screens, that are screens-first today and expose read access to the other drivers. The principle is full parity. The road to get there is in active development and visible in the changelog.
Deliverability is still your sender. Reviewed rows can use a separate configured SmartLead handoff or admin-published webhook automation. Only the webhook automation records a durable delivery result. Coil does not currently provide inbox-placement or mailbox-warmup checks. What happens after handoff is your provider, not us. Warming, domain reputation, suppression lists, and the rest of the deliverability story belong to your sender. We will not pretend otherwise.
ICP fit is still your call. The recipes ship typed steps for filtering, enrichment, and verification. Validation reports structural and publication issues before a run; provider connections are checked when the corresponding step executes. What the recipe cannot tell you is whether your ideal customer profile is actually well-defined. If you queue a scrape for VP Sales at any company between 11 and 10,000 people, you will get 2,000 mostly-irrelevant rows. The tool is sharp. The aim is yours.
Outside the founder wedge, we are unproven. Coil is built for founders running their own outreach. Larger sales teams with custom workflows, dedicated RevOps engineering, and bespoke data models may need more than we currently ship. The architecture is capable of supporting them, but we have not optimized for that audience yet, and we would rather say so than oversell.
6. Beta honesty.
Coil is in open beta. The product, organization-scoped data, route-level actor attribution, and durable run records are real, but a comprehensive browsable audit event surface remains roadmap work and the pricing model is not finalized. Today, that means everything is free. No card on file, no auto-charge, no upgrade nag. The reason is not generosity. The reason is that we want to see what real usage looks like before we put a number on it, and the only way to do that is to let people use the product without a meter running.
When beta ends, two things happen. First, you get 30 days of advance notice. The notice will name the new tiers, the limits, the price per tier, and the date the new terms take effect. Second, the same notice will include a public rationale: what real usage looked like across the beta cohort, why we picked the tiers and limits we picked, and what we explicitly chose not to charge for. If the new terms work for you, you add a card. If they do not, you walk with your data and a working CSV export. The methodology is the same on the way out as on the way in.
See /pricing for the canonical version of those commitments. This page is the methodology behind them.
FAQ.
Is parity across the dashboard, API, and CLI actually complete today?
No. Core lead, scrape, recipe, and automation workflows share services, but some admin actions deliberately require a human session and a few operator views remain dashboard-first. The repository parity matrix records those boundaries.
What does agent-operated mean in practice?
Coil organization API keys authenticate machine actors. The JSON CLI and capability manifests give an agent structured commands and return shapes, while role gates and explicit confirmations preserve human control. Coil does not currently ship an MCP server.
Why call out beta so much on a methodology page?
Because the methodology includes the commitments. Coil is free during open beta. When beta ends, the published commitment is 30 days of advance notice plus a public rationale that explains the chosen tiers and the usage data that informed them. Methodology without those promises would be lab talk.
Can an agent do everything a human can do?
Not yet. Core lead, scrape, recipe-run, automation-run, export, and actor-scoped preference workflows have machine-callable surfaces. Publication, provider credential mutation, API-key management, Actor Lab approvals, and destructive org-shared actions remain human-admin controlled, while some operator views are still dashboard-first. The parity matrix records the route-level boundary.
Read next.
- PILLAR · WHOAI cold outreach for foundersWhy the founder doing their own outreach is the beachhead audience.
- PILLAR · WHATAgent-driven lead genThe category Coil is competing in, and why it is the next stack.
- PRODUCT · DEEP DIVEAgent API and CLI installSkill manifests, install snippets per client, compatibility matrix.
- CONTEXTSecurity and data partitioningAuth, Postgres org isolation, agent access, and what we have not done yet.
Try it with the AI you already use.
One workspace. Three interfaces. Free during open beta, no card on file. Use the dashboard directly or operate supported workflows through the authenticated API and JSON CLI.
The methodology