Error format
All error responses share the same envelope:code field is a stable string identifier — use this in your error handling logic. The message field is for humans and may change over time.
Error codes
| HTTP Status | Code | Description |
|---|---|---|
400 | bad_request | Malformed request body or invalid query parameters |
401 | unauthorized | Missing, invalid, or expired authentication credentials |
403 | forbidden | Authenticated but key lacks required scope |
404 | not_found | Resource does not exist (or you don’t have access to it) |
405 | method_not_allowed | HTTP method not supported for this endpoint |
409 | conflict | Request conflicts with existing state (e.g. already following trader) |
422 | quota_exceeded | Business rule quota exceeded (e.g. max 10 API keys) |
429 | rate_limited | Too many requests — back off and retry |
500 | internal_error | Unexpected server-side error |
Examples
400 — Bad request
401 — Unauthorized
- You’re sending the
Authorization: Bearer <key>header - The key hasn’t been revoked or expired
- For key management endpoints, you’re using a Privy JWT, not an API key
403 — Forbidden
POST /api/v1/traders with a key that only has traders:read.
404 — Not found
409 — Conflict
POST /api/v1/traders when you attempt to follow a wallet you’re already copying.