---
title: "AI Agent API Cost Control: Cap Web Data Spend | Perceptlayer"
description: "Cap an agent's web data spend per run: credit arithmetic for 8 and 20 calls per task, a Python budget wrapper, and why failed calls cost 0 credits."
url: https://perceptlayer.com/blog/ai-agent-web-data-costs
---

[Blog](https://perceptlayer.com/blog) / [AI agents](https://perceptlayer.com/blog/category/ai-agents)

# AI Agent API Cost Control: Cap Web Data Spend

22 Oct 2026 Perceptlayer 7 min read

AI agent API cost control comes down to two numbers: the credits one call costs and the maximum number of calls one run may make. On Perceptlayer a successful call costs the credits shown on its endpoint, which is 1 credit for nearly all of them, and a failed call costs nothing. Multiply calls per run by runs per month, add a hard cap in your own code, and the worst case is known before the agent starts.

## Key takeaways

-   Worst-case spend per run is `max_calls × credits_per_call`. With a cap of 20 calls at 1 credit, no run can cost more than 20 credits.
-   At the Starter rate of $0.80 per 1,000 calls, a run capped at 20 calls costs at most $0.016. At the Scale rate of $0.50 per 1,000 calls, it costs at most $0.01.
-   Failed calls return `X-Credits-Used: 0`, so retries after an error or a rate limit don't add to the credit bill.
-   Enforce the cap in the code that executes tool calls, not in the prompt. A model can ignore an instruction to stop; a wrapper that raises an exception can't be ignored.
-   Web data credits are separate from model token costs. This article covers only the data side.

## Why do agent data costs drift?

Agents decide at run time how many calls a task needs, so the bill depends on model behaviour as much as on traffic. A model that keeps refining a query or loops on an empty result makes more calls than you planned. Per-call pricing is fine. The unbounded loop is the problem, and the fix is a ceiling the loop can't pass.

Prepaid credits help because the account itself has a ceiling. The service is prepaid: purchased credits last 12 months, with no subscription and no seats. When the balance runs out, calls return `insufficient_credits` (402) and nothing more is debited, so a runaway agent stops at the balance you loaded. A per-run cap keeps one run from eating that whole balance.

## How do you calculate credits per agent task?

Count the calls one task needs, multiply by the credits per call, and keep two figures: the typical case and the capped worst case. For endpoints that cost 1 credit, calls and credits are the same number. Check the cost shown on each endpoint you give the agent, because the cap should be in credits if any endpoint costs more than 1.

Take an example agent that answers a research question. Assume it typically makes 8 calls per task and you cap it at 20. These are example figures for the arithmetic, not measurements. Per run, that's 8 credits typical and 20 credits worst case.

| Pack | Price | Credits | Cost per 1,000 calls | Typical run (8 calls) | Capped run (20 calls) |
| --- | --- | --- | --- | --- | --- |
| Free tier | $0 | 1,000 per month | $0 | $0 | $0 |
| Starter | $10 | 12,500 | $0.80 | $0.0064 | $0.016 |
| Growth | $50 | 83,000 | $0.60 | $0.0048 | $0.012 |
| Scale | $200 | 400,000 | $0.50 | $0.004 | $0.01 |

Run counts follow from the credits. The free tier's 1,000 credits cover 125 typical runs (1,000 ÷ 8) or 50 capped runs (1,000 ÷ 20). The Starter pack's 12,500 credits cover 1,562 typical runs or 625 capped runs. At 500 tasks a month, typical spend is 4,000 credits, and the cap bounds the worst case at 10,000 credits, which fits inside the Starter pack's 12,500.

## Why don't failed calls count against the budget?

A failed call returns an HTTP status, a JSON error body and the header `X-Credits-Used: 0`. Only a successful response debits credits. So the retries an agent makes after a `rate_limited` (429, the status [RFC 6585](https://www.rfc-editor.org/rfc/rfc6585#section-4) defines for too many requests) or `source_error` (502) response don't change the credit total.

Take a run that makes 8 successful calls and hits 3 errors along the way: 8 credits, not 11. The three failed attempts cost nothing in credits. They still cost time and model tokens, so they should count toward a separate attempt cap.

That second cap matters. An agent that retries an `invalid_parameters` (422) response forever will never be billed for it, and it will never finish either. See the [error reference](https://perceptlayer.com/docs#errors) and the [rate limit docs](https://perceptlayer.com/docs#limits).

## How do you build AI agent API cost control in code?

Put the cap in the function that executes the agent's tool calls. The wrapper below counts credits and attempts, refuses to send a request that would pass either limit, and raises `BudgetExceeded` so the agent loop stops and returns what it has. It counts each successful call at the endpoint's listed cost, which you pass in as `credits_per_call`.

```python
import os
import requests

class BudgetExceeded(Exception):
    pass

class CallBudget:
    def __init__(self, max_credits, max_attempts, credits_per_call=1):
        self.max_credits = max_credits
        self.max_attempts = max_attempts
        self.credits_per_call = credits_per_call
        self.spent = 0
        self.attempts = 0

    def call(self, url, params=None, method="GET"):
        if self.spent + self.credits_per_call > self.max_credits:
            raise BudgetExceeded(f"credit cap reached: {self.spent}/{self.max_credits}")
        if self.attempts >= self.max_attempts:
            raise BudgetExceeded(f"attempt cap reached: {self.attempts}/{self.max_attempts}")

        self.attempts += 1
        try:
            response = requests.request(
                method,
                url,
                params=params,
                headers={"X-API-Key": os.environ["API_KEY"]},
                timeout=30,
            )
        except requests.RequestException as error:
            raise BudgetExceeded(f"request failed, stopping the run: {error}") from error
        if response.status_code == 402:
            raise BudgetExceeded("account is out of credits")
        if response.ok:
            self.spent += self.credits_per_call
        return response
```

Use one `CallBudget` per run and hand its `call` method to the agent as the only way to reach the API.

```python
budget = CallBudget(max_credits=20, max_attempts=30)
url = os.environ["ENDPOINT_URL"]  # copied from the endpoint's page

try:
    response = budget.call(url, params={"q": "example"})
    print(response.status_code, f"{budget.spent} credits spent")
except BudgetExceeded as stop:
    print("stopping the run:", stop)
```

A timeout or connection error counts as an attempt and ends the run cleanly instead of crashing the loop. The credit count is a local estimate: it adds the endpoint's listed cost for each successful response and doesn't read anything from the response. Treat it as a ceiling check, and compare it with the `X-Credits-Remaining` header, which every successful response carries with your balance after the call.

Set `max_attempts` above `max_credits` so a few free failures can retry, and keep the gap small. Here 20 credits allow 20 successful calls, and the 10 extra attempts allow up to 10 failures before the run stops. See also the [requests docs](https://perceptlayer.com/docs#requests).

## What changes when the agent calls through MCP?

The MCP server at `https://api.perceptlayer.com/mcp` exposes three tools, `search_endpoints`, `get_endpoint` and `call_endpoint`. `search_endpoints` and `get_endpoint` only look things up in the catalogue and cost nothing, so `call_endpoint` is the one tool that needs a budget check. A successful `call_endpoint` costs the credits shown on its endpoint, failed calls cost nothing, and its result reports the credits used and the balance remaining. The [MCP docs](https://perceptlayer.com/docs#mcp) cover the tools.

The cap needs your own agent loop, because the loop is where tool calls get executed. Route every `call_endpoint` the model requests through a budget check, and let the loop stop when it raises. The sketch below assumes your MCP client gives you a function `send_call_endpoint(arguments)` that runs the tool and returns its result; `credits_per_call` is the cost listed on the endpoint.

```python
class McpBudget:
    def __init__(self, max_credits, credits_per_call=1):
        self.max_credits = max_credits
        self.credits_per_call = credits_per_call
        self.spent = 0

    def call_endpoint(self, send_call_endpoint, arguments):
        if self.spent + self.credits_per_call > self.max_credits:
            raise BudgetExceeded(f"credit cap reached: {self.spent}/{self.max_credits}")
        try:
            result = send_call_endpoint(arguments)
        except Exception as error:
            raise BudgetExceeded(f"tool call failed, stopping the run: {error}") from error
        if not getattr(result, "isError", False):
            self.spent += self.credits_per_call
        return result
```

MCP marks a failed tool call with `isError` in its result (see the [MCP tools specification](https://modelcontextprotocol.io/specification/2025-06-18/server/tools)), which is what the wrapper checks before counting credits. In the loop, when the model asks for `call_endpoint`, call `budget.call_endpoint(...)` instead of the client directly. Catch `BudgetExceeded` outside the loop and return what the agent has so far. As with the HTTP wrapper, the credit count is a local estimate, not a figure read from the response.

The related walkthrough, [Claude MCP Web Search: Live Results for an Agent](https://perceptlayer.com/blog/claude-agent-live-search-mcp), shows the tools in use.

## How should you size a balance for an agent?

Size the balance for the capped worst case, then watch the typical case. Take runs per month × cap × credits per call. For 500 runs capped at 20 calls, that's 10,000 credits, which the Starter pack's 12,500 credits cover for $10. For 5,000 runs, it's 100,000 credits at the cap and 40,000 at 8 calls per run. One Growth pack (83,000 credits, $50) covers the typical 40,000. Two Growth packs (166,000 credits, $100) cover the 100,000-credit worst case. A Scale pack ($200) holds 400,000 credits at a lower rate per call, so it only pays off if you'll use most of it within the 12 months credits last.

Start on the free tier. Every month after you verify an email address you get 1,000 free credits, with no credit card, which is enough to measure your real calls per task with a cap in place.

The [credits docs](https://perceptlayer.com/docs#credits) and the [pricing page](https://perceptlayer.com/pricing) have the details and the packs. [Get a free API key](https://perceptlayer.com/signup), add the wrapper above, and run 20 tasks before you decide on a pack. More agent guides are in the [AI agents category](https://perceptlayer.com/blog/category/ai-agents).

## Frequently asked questions

### Do failed calls use credits?

No. A failed call returns an HTTP status, a JSON error body with a `code`, `message` and `request_id`, and the header `X-Credits-Used: 0`. Only a successful response debits credits. Failed attempts still take time, so cap attempts as well as credits, and see the [error docs](https://perceptlayer.com/docs#errors) for each code.

### How much does an agent run cost at 20 calls?

At 1 credit per call, a run capped at 20 calls uses at most 20 credits. That's $0.016 at the Starter rate of $0.80 per 1,000 calls, $0.012 at the Growth rate of $0.60, and $0.01 at the Scale rate of $0.50. Calls to the rare endpoint that costs more than 1 credit change the maths.

### Should the budget live in the prompt or in code?

In code. A prompt that says "make at most 20 calls" is a request the model can miss after a long context or a confusing result. A wrapper that counts credits and raises an exception at the cap is deterministic. Use the prompt to tell the agent what to do when the wrapper stops it.

### What happens when my credits run out mid-run?

The API returns `insufficient_credits` with HTTP status 402, and nothing is debited for that call. In the example wrapper, a 402 raises `BudgetExceeded`, which ends the run cleanly. Purchased credits last 12 months, and there is no subscription.

### Does the free tier cover testing an agent?

Yes. Every account gets 1,000 free credits each month after verifying an email address, with no credit card. At a cap of 20 calls per run, that's 50 capped runs a month, or 125 runs at 8 calls each, which is enough to measure real calls per task before buying a pack.

ai agents cost control credits mcp budgeting

## More from the blog

1.  [AI agents](https://perceptlayer.com/blog/category/ai-agents) 22 Oct 2026 Perceptlayer 8 min read
    
    ## [Claude MCP Web Search: Live Results for an Agent](https://perceptlayer.com/blog/claude-agent-live-search-mcp)
    
    Add the Perceptlayer MCP server to Claude, let the agent call the Google Search endpoint, and count its cost: 1 credit per search call.
    
2.  [API guides](https://perceptlayer.com/blog/category/api-guides) 22 Oct 2026 Perceptlayer 7 min read
    
    ## [Zillow Listings API: Get Property Data as JSON](https://perceptlayer.com/blog/zillow-listings-api-json)
    
    One GET to /v1/zillow/search returns listings near a point as JSON with price, beds, baths and address. Parameters, a real response, 1 credit per call.
