An AI agent can overspend a paid data API, and the mechanism is almost never a clever failure. It is a retry loop, a re-run of a list that was already enriched, a fan-out that turned one task into 500, or a filter that matched 50,000 rows instead of 50. Four controls stop all four: a required pre-authorisation quote before any paid call, idempotency keys on writes, per-key rate limits, and a shared wallet that is a hard ceiling. Cleanlist implements the first as a hard gate: estimate_cost returns an HMAC-signed quote with a five-minute life, and six paid operations refuse to run without one. Limits are 60 requests a minute per organisation, 30 per API key, and 60 People Searches a UTC day per key.
Last updated: September 1, 2026. Cleanlist limits, error codes and prices on this page are the published values as of that date. Third-party claims carry the vendor page they were fetched from.
Can an AI agent actually overspend a B2B data API?
Yes, on most of them, and the reason is structural. An agent decides what to call from a natural-language instruction, and nothing about that instruction carries a budget. If the API meters per record and the agent holds a valid key, the only thing between a bad plan and a bill is whatever the vendor put in the path. Most vendors put in a balance and a rate limit, both of which are ceilings measured in money you already spent. The control that actually works is earlier: make the paid call impossible until the agent has asked what it costs and been handed something signed. On Cleanlist, an agent that has not called estimate_cost cannot run bulk enrichment at all; the endpoint returns HTTP 400 with the code quote_required (Cleanlist errors and rate limits).
What are the failure modes that actually run up a bill?
Four, in rough order of how often they happen. A retry loop: the call times out, the agent's HTTP client retries, and the vendor treats each attempt as a new billable job. Duplicate work: the agent re-enriches a list it already enriched last week, because nothing in the conversation told it that. Runaway fan-out: one instruction becomes a per-row loop, and 500 rows become 500 paid calls with no aggregate ceiling anywhere. A mis-scoped filter: a search meant to match 50 people matches 50,000, and the agent enriches all of them because that is what it was told to do. None of these are model errors in the interesting sense. Every one is a missing guardrail in the API surface, which is why the fixes below are all vendor-side mechanics rather than prompt engineering, and why Cleanlist puts the first of them in front of every paid call.
How does a retry loop overspend a data API?
Because a retry is indistinguishable from a new request unless the API is built to tell them apart. An enrichment job that takes 40 seconds and a client that times out at 30 produces a second dispatch of the same work, then a third. The vendor sees three jobs and bills three. The defence is a client-supplied key that lets the server recognise the replay and return the first result instead of doing the work again. Where that key does not exist, and on Cleanlist's enrichment routes it does not, the discipline moves to your side: raise the client timeout above the job's real duration, make the dispatch call non-retryable in your HTTP layer, and keep your own ledger of dispatched ids. Blind retry against a metered endpoint is the single most expensive default in an agent stack.
What stops an agent re-enriching the same list twice?
Nothing the model knows. An agent has no memory of last Tuesday's run unless you give it one, so "enrich the pipeline list" run twice is two bills. Three things reduce it. Keep the enriched-at timestamp on the row and instruct the agent to filter on it, which is cheap because reading a list costs nothing. Enrich into a named list rather than an ad-hoc one, so the second run has something to compare against. And read the quote: on Cleanlist the estimate returns the row count the server derived from the list, so an agent that quotes a job it thinks is 40 rows and sees 4,000 come back has been handed the discrepancy before it spends anything. The quote is a dry run you are allowed to ignore, which is why it works best when the API refuses to proceed without it.
What is a pre-authorisation quote, and why is it the strongest control?
It is a two-phase commit for money. Phase one, the agent describes the job and the server prices it, returning a signed token bound to that exact job shape. Phase two, the agent submits the job with the token attached, and the server reprices the work at execution time and refuses if the real cost has grown past what was quoted. The reason it beats a balance cap and a rate limit is that both of those only bind after the spend. A quote binds before it, and it binds to the shape of the job, so an agent cannot quote a 10-row job and then submit 10,000 rows under the same token. Cleanlist binds the quote with HMAC-SHA256 to the tool, the list or filters, the scope, the row count and the organisation (Cleanlist credits and quotes).
What does the Cleanlist estimate_cost quote actually return?
A quote object an agent can act on without guessing. The Cleanlist estimate carries quote_id, the tool and scope it is bound to, row_count, the per-row ceiling, estimated_cost, available_credits, a boolean sufficient, an expires_at five minutes out, single_use: true, and the signature algorithm. That is enough for an agent to make a decision on its own: if sufficient is false, stop and tell the human the shortfall instead of dispatching into a failure. Calling the estimate costs 0 credits and can be repeated as often as the agent likes, so exploring the price of five different scopes before choosing one is free. When the quote references a saved list, the row count is read off the list on the server and the client's own count is ignored, so a large list cannot be under-quoted.
Which Cleanlist operations refuse to run without a quote?
The paid ones, which is the point. On Cleanlist a signed quote_id is required before enrich_list, add_person_enrichments, add_company_enrichments, run_smart_agent, sync_to_crm and sync_to_sequencer. Single-record person and company enrichment accept a quote and do not require one, because the ceiling on a single record is 11 credits and gating it would only add a round trip. Everything an exploring agent does is free and ungated: whoami, search_people, search_companies, get_lists, list_leads_in_list, estimate_cost, creating and deleting lists, and saving search results into a list. An agent can size a market, refine an ICP twenty times and read every list in the organisation without touching the balance.
What happens when the real cost exceeds the quote?
The run is refused, with a machine-readable reason rather than a silent partial charge. Cleanlist publishes the codes: quote_required when no quote was attached, quote_mismatch when the quote was signed for a different job shape, quote_expired when it is older than its five-minute life, quote_already_redeemed when the same quote is presented twice, and spend_cap_exceeded when the repriced job would cost more than the quote allowed. Running short of balance is its own case: HTTP 400 with insufficient_credits, carrying the estimated cost, the available credits and the exact shortfall so the agent can say how much to top up instead of retrying blindly. Every Cleanlist error carries a retryable flag, which is the field an agent loop should branch on (Cleanlist errors and rate limits).
Do idempotency keys protect an enrichment run on Cleanlist?
Only on ingest, and this is worth stating plainly because the wrong assumption here is expensive. Cleanlist's ingest routes take an idempotency_key: add-leads and CSV import both accept one, and a replay inside 24 hours returns idempotency_replayed: true without re-charging. The enrichment routes take no idempotency key. A retried dispatch against POST /enrichment/bulk is a new billable workflow. So the rule for anyone building on Cleanlist is: never blind-retry an enrichment dispatch, keep your own ledger of enriched ids, and set your client timeout above the job's real duration. Cleanlist's own API page says the same thing in the same words, which is the version to trust over any summary of it.
What rate limits does Cleanlist enforce, and what do they protect?
Three published limits, and they protect throughput rather than money. Cleanlist allows 60 requests a minute per organisation across all keys and members combined, 30 requests a minute per individual API key, and a hard cap of 60 People Searches per UTC day per key. Organisations on an AppSumo lifetime licence without a paid plan get a reduced 30 a minute per organisation. Exceeding any of them returns HTTP 429 with a Retry-After header and retry_after_ms in the body. The daily search cap is the one that bites agent workflows first, because an agent looping over many narrow searches exhausts 60 in an afternoon. Batch filters into fewer, broader searches and page through the results rather than issuing a search per account.
How does a shared organisation wallet work as a hard ceiling?
It is the last line, and it is genuinely hard. Cleanlist credits are pooled at the organisation level, and the same balance is drawn on by the app, the REST API and the MCP server. There is no separate agent allowance, which cuts both ways: the most an agent can consume is the balance you already hold, and an agent spending badly is spending your team's month. GET /credits/balance costs 0 credits, so a well-built loop reads the balance before a batch and stops itself well above zero rather than discovering the floor. What Cleanlist does not offer today is a per-key sub-budget, so if you want an agent capped below the org balance, the cap has to live in your own orchestration layer. Say that out loud in a design review rather than assuming it.
What are OAuth scopes good for here, and what are they not?
Scopes bound capability, not cost, and conflating the two is a common review error. Cleanlist checks a clapi_ bearer key against 14 OAuth scopes, and every endpoint requires a specific one, so a credential without enrich:write gets HTTP 403 with insufficient_scope and the response names both the required and the granted scopes. That is a real control: a read-only integration genuinely cannot spend. What it is not is a budget. Cleanlist grants scopes per user rather than per key today, so you cannot currently mint a key narrower than the user who created it, and there is no read-only key mode as a result. Each user can hold up to 10 active keys (Cleanlist authentication and scopes).
Which parts of an agent workflow cost nothing?
More than most people expect, and designing around it is the cheapest optimisation available. On Cleanlist, identity checks, people search, company search, reading lists, reading the rows in a list, creating a list, saving search results into a list, deleting a list, checking the balance, running a cost estimate, polling a job's status and exporting the results all cost 0 credits. Credits move on exactly four things: enrichment, smart agents, CRM sync and sequencer sync. The design consequence is that the expensive step should always be the last one. Let the agent search, refine, save, read and quote as many times as it needs, and spend only once the human has seen the number.
How do I design an agent loop that cannot run away overnight?
Six rules, in the order they matter. One: quote before every paid call and branch on sufficient, not on optimism. Two: make paid dispatches non-retryable in your HTTP client, and give them a timeout longer than the job. Three: keep a ledger of ids you already enriched, and filter against it before every run. Four: cap fan-out explicitly, so a per-row loop has a maximum row count that the agent cannot argue its way past. Five: read the balance before each batch and refuse to start below a floor you set. Six: put a human approval between the quote and the run for anything above a threshold you would notice on an invoice. None of that is specific to Cleanlist. It is what any paid, agent-callable API needs from the caller's side.
What does Cleanlist not have, stated plainly?
Five gaps that belong in a security or architecture review. REST API v2 has no webhooks, so every async result is retrieved by polling; the legacy v1 API has webhook delivery, v2 does not. There is no published uptime SLA. There is no SOC 2 report. The MCP server is in beta, gated to self-serve accounts, with AppSumo licences excluded, and it is not covered by the 14-day full-access trial, which includes every feature except the public API and MCP. And there is no idempotency key on the enrichment routes, as above. If your review needs formal attestations, wait for them rather than assuming them. The Cleanlist MCP page publishes the same list.
Do other B2B data vendors ship MCP servers?
Several do, and any page telling you Cleanlist is the only one has not checked. Probing on September 1, 2026, all five of these endpoints answered an unauthenticated JSON-RPC request with HTTP 401 rather than a 404, which is a live server refusing an anonymous caller: Apollo at mcp.apollo.io/mcp, Clay at api.clay.com/v3/mcp, ZoomInfo at mcp.zoominfo.com/mcp, Hunter at mcp.hunter.io/mcp and Lusha at mcp.lusha.com. Hunter documents the widest access of the group: its FAQ states that Hunter's MCP works with all Hunter plans including free accounts, with existing request limits and credits applying (hunter.io/mcp, fetched September 1, 2026). Apollo publishes its server at apollo.io/product/mcp and Lusha documents 24 tools at docs.lusha.com/mcp-docs. A GTM MCP server is not a rare thing in 2026.
So what is actually different about the Cleanlist server?
One narrow claim, and it is the only one worth making. Cleanlist is the server that refuses a paid call without a signed quote. Of the five vendor servers above, none publishes an equivalent documented pre-authorisation gate as of September 1, 2026, and several document the opposite arrangement, where an authorised agent spends credits directly and your protection is the balance. Cleanlist's second defensible property is adjacent: search costs 0 credits and export is not metered, so an agent can explore an entire market without spending, and taking the data out afterwards costs nothing. Apollo's pricing page is explicit that its export credits are consumed whenever a contact leaves Apollo, including CSV, CRM and Person API enrichment (apollo.io/pricing, fetched September 1, 2026).
Cleanlist: Best for engineering and RevOps teams pointing an autonomous agent at a paid data API. It gates six paid operations behind an HMAC-signed cost quote across a 30+ tool MCP server, with 0-credit search and an unmetered export, and REST API access starting at $229/month.
What does API and MCP access cost on Cleanlist?
The API is a plan gate, the MCP server is an account gate. Cleanlist REST API v2 requires Pro at $229 a month or above on self-serve, or an AppSumo Tier 5+ licence, and keys are generated in the dashboard with no approval queue. The Cleanlist MCP server is in beta on self-serve accounts and excluded from AppSumo licences, and is gated by account type rather than tier. Neither is included in the 14-day full-access trial. Credits are the same on both surfaces and come from one organisation wallet: 1 for a verified email, 10 for a direct dial, 11 for both, 1 for a company enrichment, 0.2 a lead for CRM or sequencer sync, and 0.5 to 3 a lead for a smart agent. Full tiers are on the pricing page.
FAQ
Can I set a hard spend cap for an agent on Cleanlist?
Per job, yes; per key, not today. The Cleanlist signed quote is a per-job cap, and it is enforced server-side: the run is refused with spend_cap_exceeded if the repriced work would cost more than the quote allowed. The organisation credit balance is a second cap, and it is absolute, because the app, the REST API and the MCP server all draw on the same wallet. What Cleanlist does not offer yet is a per-key or per-agent sub-budget below the organisation balance. If you need an agent capped at, say, 500 credits a day, that ceiling has to be implemented in your own orchestration: read GET /credits/balance before each batch, track your own consumption, and stop the loop yourself.
What is the difference between credits reserved and credits charged?
A reservation is a ceiling, not a bill. Cleanlist reserves the maximum possible cost when an async job dispatches, then refunds the unused portion when the workflow settles, and the terminal payload reports what was actually charged alongside what was refunded. A 10-row job at the 11-credit full scope reserves 110 credits; if four rows return an email only and one returns nothing, the settled charge is lower and the difference goes back. This is why an agent reading credits_reserved and reporting it as spend will consistently overstate the bill. Read the settled figure from the status poll, which costs 0 credits, and log that.
Does the Cleanlist MCP server give an agent access to my CRM?
Only outward, and only through a sync tool you can revoke. The connector authorises over OAuth scoped to your Cleanlist organisation, so no raw API key sits inside a chat client, and revoking the connector from your client's settings cuts the agent off from both the data and the credits immediately. Sync pushes enriched leads out to HubSpot, Salesforce or Outreach, and to Lemlist as a sequencer, at 0.2 credits a lead. Note the separate exposure that has nothing to do with Cleanlist: whatever a tool returns enters the model's context, so emails and phone numbers an agent retrieves are handled under your agreement with the model provider. A data-processing review has to cover both halves.
Is a rate limit a spend control?
No, and treating it as one is how teams get surprised. A rate limit caps requests per unit of time, which caps how fast money leaves rather than how much. Cleanlist's 60 requests a minute per organisation and 30 per key are throughput protections; at 11 credits a row they permit a substantial spend inside an hour. The daily cap of 60 People Searches per key is closer to a real limiter, but searches are free, so it constrains discovery rather than cost. The controls that bind cost are the required quote, the shared wallet, and whatever ceiling you enforce in your own loop. Rank them in that order in a design review.
What should I log from an agent that spends credits?
Five fields, and they fit in one line per call. The quote_id and its estimated_cost, so you can reconcile intent against outcome. The workflow_id, so a job is traceable after the conversation is gone. The settled charge from the terminal status poll rather than the reservation. The error code when a call fails, since Cleanlist codes are machine-readable and retryable tells your loop whether to try again. And the identifier of every record you enriched, because with no idempotency key on the enrichment routes, that ledger is the only thing standing between you and paying twice for the same row.
Run this on your own contacts
Put your own contacts through the multi-provider waterfall and export the result. 250 credits, 3 seats, 14 days. No card required. Bulk CSV upload lands on Starter at $79/mo, and CRM import and sync on Pro at $229/mo.
250 credits, 3 seats, 14 days. No card required.
