Advanced guide / Chapter 1 of 7
How a call flows through ACPpotamia.
ACPpotamia sits between your agent and the model provider. You keep your OpenAI or Anthropic SDK and change one thing, the base URL. From then on each call makes two stops before it reaches the provider. The first is the Cloudflare location nearest your agent. The second is your team's control object: one small server that holds all of your team's limits and makes each allow-or-block decision in a single step, so two agents can't both squeeze through the last dollar.
Step by step
- The nearest Cloudflare location checks your ACPpotamia key. An unknown or revoked key gets HTTP 401 and the call stops there.
- Your team's control object runs its checks in a fixed order (shown below). If one fails, the call is refused with a specific code and the provider never sees it.
- If everything passes, the control object holds the call's estimated cost against every budget it counts toward: team, API key, tenant and session.
- ACPpotamia forwards the call with your own provider key. We pass that key through and never store it.
- The answer streams back to your agent byte for byte while ACPpotamia counts tokens. If a budget runs dry mid-stream, the stream ends with an error event in the provider's own format, so your SDK reports it normally.
- When the call ends, the provider's real usage replaces the estimate and any difference goes back into the budget.
- A few seconds later the call shows up in the audit log, whether it was allowed or blocked.
The checks, in order
The headers you send
| Header | Purpose |
|---|---|
Authorization: Bearer acp_… or X-ACP-Key | Your ACPpotamia key. |
X-Upstream-Key (or x-api-key for Anthropic) | Your provider key. Passed through, never stored. Not needed for test keys. |
X-ControlPlane-Agent-Id | Which agent is calling. Groups activity and spend. |
X-ControlPlane-Session-Id | One task. Scope for loop detection, session limits and stopping one task. |
X-ControlPlane-Tenant-Id | Your end-customer, for per-customer budgets (Pro, Enterprise). |
X-ControlPlane-FailMode | open or closed: what happens if limits cannot be checked. See chapter 7. |
The headers you get back
| Header | Meaning |
|---|---|
X-ControlPlane-Decision | allow, block, fail-open or fail-closed |
X-ControlPlane-Block-Reason | The exact reason when blocked, such as tenant_budget_exhausted. |
X-ControlPlane-Budget-Remaining-USD | Team budget left after this call's hold. |
X-ControlPlane-Overhead-Ms | Time ACPpotamia added before the provider was called. |
X-ControlPlane-Request-Id | The call's id in the audit log. Quote it to support. |
What is stored, and what is not
- We never store your provider API keys.
- We keep a record of every call for 365 days: when it happened, which agent, session and tenant, the model, tokens, cost, outcome and timing.
- Request and response text is kept only if you turn on payload logging (Pro and Enterprise), and then only the first 64 KB of each.
Tip. Watch
X-ControlPlane-Overhead-Ms in your logs. It's usually under 100 ms. The first call after a quiet spell can be slower, because your team's control object has to wake up.