# How to set a monthly budget for an agent (/blog/set-a-monthly-budget-for-an-agent)

![Illustration: A small friendly robot with a round camera-eye head wearing a plain empty name badge on its chest holds a coin beside a coin-operated parking meter on a post.](/blog/set-a-monthly-budget-for-an-agent/hero.webp)

A monthly budget for an agent on CoreSpeed is a spend cap in credits attached to the API key the agent uses. Once the month's recorded usage reaches the cap, later metered calls with that key are refused with `key_spend_limit_exceeded` until the month rolls over or you raise the cap. The organization wallet is a second, outer boundary.

**A budget that belongs to the agent**

1. **Create the agent identity** (Dashboard, Settings, or manage\_\_agents\_create) — You become its owner; it inherits nothing from you.
2. **Mint a key with a monthly cap** (Dashboard, API keys, or manage\_\_agents\_key\_create) — The cap is a number of credits.
3. **Put the key where the job runs** (CORESPEED\_API\_KEY; keys are per environment)
4. **Verify with a free call** (memory\_\_list\_memory costs 0 credits)
5. **Share the connections it needs** (an agent key sees shared accounts only)
6. **Read the spend** (Dashboard, Activity and Billing; cs usage)

The cap, the trail and the approval cards belong to a named agent.

## Which key should carry the cap? \[#which-key-should-carry-the-cap]

Caps attach to API keys. The browser sign-in path has only the wallet stop, so an agent you want budgeted on its own needs a key.

There are two kinds. An `sk-cs-` member key acts as you: it reaches your private connections and the organization's shared ones, and its activity is attributed through you. An `sk-csa-` agent key belongs to an agent principal with an identity of its own. It reaches shared connections only, never a member's private ones, and its activity is attributed to the agent, whose owner answers for it.

For an unattended job you operate, a cron on your own server or a nightly run, use an agent key. The budget, the trail and the approval cards then belong to a named agent rather than to whichever member happened to create the key. The [authentication page](/docs/authentication) has the full table of credentials.

## How do you set it up? \[#how-do-you-set-it-up]

1. Create the agent identity. Any member can, in Dashboard → Settings or with `manage__agents_create` from a signed-in client. You become its owner. Ownership is accountability: the agent inherits neither your connections nor your role.
2. Mint a key with a monthly cap. From Dashboard → API keys, or with `manage__agents_key_create` under a member session. The cap is a number of credits. Per-action prices are on the [pricing page](/pricing); for a sense of scale, `web__search` is 14 credits per request covering up to 10 results, and most social reads are 1.5 credits per request.
3. Put the key where the job runs, in an environment variable such as `CORESPEED_API_KEY`, and point the client at it. Keys are per environment, so a production key is rejected on staging.
4. Verify with a free call. `tools/list` and every memory operation cost 0 credits, so a `memory__list_memory` call proves the key works without spending.
5. Share the connections the agent needs. An agent key only sees shared accounts, so a Slack or GitHub account it should use must be connected as shared.

```json
{
  "mcpServers": {
    "corespeed": {
      "type": "http",
      "url": "https://api.corespeed.io/mcp",
      "headers": { "Authorization": "Bearer sk-csa-..." }
    }
  }
}
```

Read the key from the environment rather than writing it into the file. In Claude Code, `claude mcp list` hides headers and `claude mcp get` prints them, key included, so keep `get` out of transcripts.

## What does a refusal look like? \[#what-does-a-refusal-look-like]

A refusal for standing arrives on `/mcp` as HTTP `200` with `result.isError: true`. The tool did not run. Branch on `structuredContent.error.code`.

| Boundary                               | Code                       | What still works                         | Who clears it                                       |
| -------------------------------------- | -------------------------- | ---------------------------------------- | --------------------------------------------------- |
| Key's monthly cap                      | `key_spend_limit_exceeded` | discovery, account reads, key management | the month rolls over, or a member raises the cap    |
| Organization wallet past its threshold | `payment_required`         | discovery, account reads, key management | adding credit: plan credits or a top-up             |
| Administrative suspension              | `org_suspended`            | the same                                 | an administrative action; balance does not clear it |

None of these clears on retry. Retrying the same call only produces the same refusal, so the agent should stop and report the code.

Caps are request-boundary guardrails, not reservations. The check happens before a call runs; an action already in flight can finish above the remaining amount before its final cost is recorded. Set the cap a little below the number you have in mind.

Credit itself comes from three places. 3,000 free credits arrive when your first organization is created, no card required, and expire 90 days after the grant. CoreSpeed Pro adds 10,000 credits each month, reset monthly, plus top-ups from $5 to $1,000 that never expire. The Free plan has no top-up. The [billing page](/docs/billing) describes the wallet and the ledger.

## How do you read what the agent spent? \[#how-do-you-read-what-the-agent-spent]

Dashboard → Activity lists every call with action, actor, outcome, surface and time. Calls made with the agent key show the agent as the actor. Members see their own actions; org admins see the org. Each record references its charge where one exists, and the dashboard joins the two, so the cost of a run is readable next to what the run did. Calls refused before any tool ran leave no record.

Dashboard → Billing shows the balance, each key's cap and the itemized ledger. From a terminal, `cs usage` prints the same spend. Media generation is billed after success at the model's rate; failures, cancels and expiries never charge.

If Smart Approval is on, a write the agent makes that your policy asks about pauses, and the card reaches the agent's owner. An agent cannot approve its own action.

## FAQ \[#faq]

**Does the cap stop a call that is already running?** No. The cap is checked at the request boundary. A call in flight finishes, and its cost is recorded after.

**Can the agent raise its own cap?** No. `manage__keys_*` and `manage__agents_*` run only under a member session. An API key gets `200` with `isError: true` and the code `jwt_session_required`.

**Do memory calls count against the cap?** No. Memory operations and `tools/list` cost 0 credits per call.

**What if I want the agent stopped entirely?** Suspend it. Every request then answers `403 agent_suspended`, the keys stay intact, and the owner or an org admin can resume it. Retire is terminal: the record survives for attribution in the [activity trail](/docs/activity), and its keys answer `401 invalid_api_key`.