Authentication
Send your Bavest API key in the x-api-key header. Where keys come from, the free trial, quotas, error codes and key rotation.
Every request to https://api.bavest.co/v2/... needs an API key in the x-api-key header. There is no OAuth flow and no session: the key identifies your account and its plan.
Send the key
Put the key in an environment variable such as BAVEST_API_KEY and send it as a header on every request. The code samples in the API reference read it from there.
curl 'https://api.bavest.co/v2/equities/profile?symbol=AAPL' \
-H "x-api-key: $BAVEST_API_KEY"import os, requests
resp = requests.get(
"https://api.bavest.co/v2/equities/profile",
params={"symbol": "AAPL"},
headers={"x-api-key": os.environ["BAVEST_API_KEY"]},
)
resp.raise_for_status()const resp = await fetch("https://api.bavest.co/v2/equities/profile?symbol=AAPL", {
headers: { "x-api-key": process.env.BAVEST_API_KEY },
});The MCP server takes the same key in the same header.
Get a key
Free trial
| Trial key | |
|---|---|
| Duration | 14 days from sign-up |
| Calls | 1,000 per month |
| Rate limit | 50 requests per second |
| Routes | All v2 routes except bulk and exports |
| After the trial | The key is switched off and refused (401 or 403). Book a plan in the dashboard to keep going. |
Quotas and rate limits
- Every key has a monthly call quota set by its plan. Each request counts once, MCP tool calls included.
- Each route in your plan takes 100 requests per second (burst 100) per key; monthly call volumes depend on the plan. Ask service@bavest.co for an enterprise plan.
- Which routes a key reaches also depends on its plan. A route outside your plan is refused, see the error table.
Check how much of this month's quota is left with GET /v2/account/quota. It answers usage, limit, remaining and period.
curl 'https://api.bavest.co/v2/account/quota' -H "x-api-key: $BAVEST_API_KEY"Errors
| Status | Meaning | What to do |
|---|---|---|
| 401 or 403 | The key is missing or refused: no x-api-key header, a mistyped key, a trial that ended, a revoked key, or a key not enabled for v2. The status alone does not tell these apart. | Retrying does not help. Check that the header is sent and the key matches the dashboard; otherwise write to service@bavest.co. |
429 Limit Exceeded | This month's quota is used up. | Wait for the next month or book a bigger plan. |
| 429, other message | Too many requests in a short time. A route that is not part of your plan also answers this way. | Wait for Retry-After seconds, then retry with backoff. If it persists on one route, check that your plan includes it. |
The OpenAPI spec documents Retry-After, X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset on 429 responses. Read Retry-After when it is present; otherwise back off exponentially.
Keep keys secret
- Never put the key in a URL. Query strings end up in server logs, proxy logs, browser history and shared links. Send it in the header only.
- Never ship the key in browser or mobile code. Call Bavest from your server and pass the results on.
- Keep it out of repositories: load it from an environment variable or a secret manager.
- The one exception is an MCP connector that cannot set headers, see MCP authentication.
Rotate a key
- On the dashboard home page, open Manage keys and choose Rotate key.
- You get a new key on the same plans. On paid plans the old key keeps working until you revoke it, so switch your apps first, then revoke the old key in the same dialog.
- On the trial plan the old key stops working at once.
Rotate when a key may have leaked or someone with access leaves. Team members using their team's key ask the account admin to rotate it.
This page as Markdown: /docs/authentication.md

