Valta Docs
Error codes
| Code | HTTP | Message | What to do |
|---|---|---|---|
| API_KEY_REQUIRED | 401 | Missing API key | Send x-api-key or Authorization: Bearer. |
| INVALID_API_KEY | 401 | Invalid or expired API key | Rotate the key in the dashboard. |
| INSUFFICIENT_API_KEY_PERMISSIONS | 403 | API key missing required permission: … | Create a key with write access. |
| API_KEY_RATE_LIMITED | 429 | API key rate limit exceeded | Back off and respect retry cadence. |
| IP_BLOCKED | 403 | IP address blocked | Contact support if unexpected. |
| TIER_LIMIT | 403 | Agent limit reached on … tier | Upgrade plan or delete unused agents. |
Validation errors return 400 with { error: string } describing the missing field.
Enforced proxy (POST /v1/chat/completions)
A denied proxy call never reaches OpenAI. Every deny has the same body — an OpenAI-style error object (so OpenAI SDKs show a readable message) plus flat fields you can match on:
json
{
"approved": false,
"reason": "per_run_limit",
"id": "allow_…",
"message": "Valta per-run limit reached for this run. No request was sent to OpenAI.",
"error": { "message": "…", "type": "valta_denied", "code": "per_run_limit" }
}
reason | HTTP | Meaning | What to do |
|---|---|---|---|
| per_run_limit | 402 | This call would push the run over its per-run cap. | Expected — stop the loop. Raise the cap on the agent page if it was too low. |
| daily_limit | 402 | Over the agent's daily cap. | Wait for the next UTC day, or raise the limit. |
| monthly_limit | 402 | Over the agent's monthly cap. | Wait for the 1st (UTC), or raise the limit. |
| plan_limit | 402 | Your Valta plan's tracked spend for the month is used up (Free $50, Builder $500, Startup $5,000). | Upgrade — the body includes plan, limit, upgradeTo, upgradeUrl. |
| plan_agent_limit | 402 | Your plan's number of Cap agents this month is used up. | Upgrade, or use an agent that's already active this month. |
| plan_key_limit | 402 | This virtual key is beyond your plan's active-key count (e.g. after a downgrade). | Revoke extra keys, or upgrade. |
| frozen | 403 | The agent is frozen. | Unfreeze it on purpose, or leave it. |
| cap_disabled | 403 | Cap isn't turned on for this agent. | Enable Cap on the agent page. |
| no_provider_key | 403 | No OpenAI key is stored for this agent. | Save one in the agent's proxy panel. |
| rate_limited | 429 | Too many requests on this virtual key in the last minute (Free 10/min). | Back off; honour Retry-After. |
| valta_unavailable | 503 | Valta couldn't make a decision, so it failed closed. | Retry later; check GET https://valta.co/v1/health. |
Other proxy responses:
| HTTP | error.code | Meaning |
|---|---|---|
| 401 | invalid_api_key | Missing, wrong, or revoked virtual key. The key must start with vk_live_. |
| 400 | stream_not_supported / missing_model / missing_messages / invalid_json | Bad request shape. Streaming isn't supported yet. |
| 502 / 504 | upstream_unreachable / upstream_timeout | Valta approved the call but couldn't reach OpenAI, or OpenAI didn't answer in 100 seconds. The estimate stays charged, since OpenAI may have run it. |
| OpenAI's own status | OpenAI's own code (e.g. insufficient_quota) | Valta approved the call and OpenAI refused it. OpenAI's error is passed through and the estimate is released. |
OpenAI SDKs don't auto-retry 402 or 403. Set max_retries=0 if you don't want the SDK retrying 429/5xx either.
Proxy key management
| Code | HTTP | Where | What to do |
|---|---|---|---|
| PLAN_VIRTUAL_KEY_LIMIT | 402 | Creating a virtual key | Your plan's active virtual keys (per account) are in use. The body names the agent(s) holding them (activeKeyAgents). Use that key, revoke it, or upgrade. |
| INVALID_PROVIDER_KEY | 400 | Saving an OpenAI key | Doesn't look like an OpenAI key (sk-…), or is a Valta virtual key. |
| LIVE_MODE_REQUIRED | 400 | Any provider-key / virtual-key route | Use a live Valta API key, not a test-mode one. |
See the proxy API reference for the endpoints themselves.