# Agent plan & your own keys

With the **Agent plan**, reports run on your own provider accounts: you send your provider keys with a start, and every engine call in that report uses them. Your keys pay the providers; the plan buys the runs, the dashboard and the history, within published limits. Prices and the current limits are on the [developers page](https://www.recomention.com/developers#pricing).

:::note
Bring Your Own Key can be switched off on a server. When it is, a start with `funding: "byok"` returns `403` and nothing runs; use `funding: "credits"` instead.
:::

## Start a report on your keys

```bash
curl -X POST https://api.recomention.com/v1/reports \
  -H "Authorization: Bearer $RECOMENTION_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(openssl rand -hex 16)" \
  -d '{
    "domain": "example.com",
    "category": "meeting scheduling",
    "description": "Booking links for sales teams",
    "plan": "FULL",
    "funding": "byok",
    "providerKeys": { "OPENAI": "sk-…", "PERPLEXITY": "pplx-…" }
  }'
```

`providerKeys` takes any of `OPENAI`, `ANTHROPIC`, `PERPLEXITY`, `GEMINI`, `GROK` and `AI_OVERVIEW` (a SERP API key in `login:password` form).

- **Bring the keys you have.** Any subset works. An engine you send no key for is listed under `enginesSkipped`, never counted as an engine that left you out.
- **One of OpenAI, Anthropic or Gemini is required.** One of them writes the questions and reads the answers.
- **Keys go with `funding: "byok"` only.** Sending `providerKeys` with `funding: "credits"` is refused and nothing starts.

## How your keys are treated

- **Used for that one report, then gone.** Your keys are held in memory while the report runs. They are never written to our database or our logs, and no response or error message ever repeats them.
- **Locked while queued.** The queued job carries your keys encrypted. The other half of the lock is destroyed when the report ends, and it expires after a day regardless, so the queued copy can never be read again.
- **Only your keys.** Every model call in a BYOK report uses the keys you sent, or a method that calls no model at all. We never fall back to ours.
- **A rejected key is stated, not scored.** If a provider refuses your key, that engine shows as skipped with the reason "provider rejected the key". It never counts as an engine that didn't name you.
- **What we keep:** that the report was BYOK, and which engines you sent a key for.

## Limits

The plan has published limits instead of "fair use":

| `limit` | What it bounds |
| --- | --- |
| `projects` | Brands (domains) per billing period. |
| `reportsPerMonth` | Reports per billing period. |
| `perDay` | Reports in any 24 hours. |
| `concurrent` | Reports running at once. |

A refusal names the limit. Without an active plan a start returns `402` with `limit: "plan"`. Past a limit it returns `429` with the limit's name, plus `Retry-After` and `retryAfterSeconds` when the wait is knowable (`perDay`, and the period limits when the period's end is known; never `concurrent`). Nothing is queued and nothing is charged. See [plan limits](/rate-limits/#plan-limits-named-in-limit).

## On your dashboard

Each report started on your keys joins the dashboard project for its domain, so every run sits in one place. You can also store provider keys in a project's settings and run reports from the dashboard, and Track runs on your own keys at no extra charge.

## With the MCP server

Put your provider keys in the MCP server's environment (`OPENAI_API_KEY`, `ANTHROPIC_API_KEY`, `PERPLEXITY_API_KEY`, `GEMINI_API_KEY`, `XAI_API_KEY`, `DATAFORSEO_API_KEY`), not in a prompt. See [MCP server](/mcp/).