Documentation Index
Fetch the complete documentation index at: https://docs.wiseyield.co/llms.txt
Use this file to discover all available pages before exploring further.
WiseYield API errors share a consistent shape so integrations can handle them uniformly. The HTTP status code communicates the class of error; the code field gives the machine-readable kind; message is human-readable; details carries structured context when applicable.
Canonical response shape
{
"error": "Validation failed",
"code": "VALIDATION_ERROR",
"message": "totalArea must be greater than 0",
"details": {
"totalArea": ["Total area must be greater than 0"]
}
}
| Field | Always present? | Notes |
|---|
error | Yes | Short, human-readable category (Unauthorized, Validation failed, Not found, …) |
code | When the error has a stable kind | Machine-readable identifier — use this for switch statements |
message | Frequently | Longer human-readable description |
details | When structured context exists | Per-field validation errors, available scopes, retry hints, etc. |
Status code classes
| Status | Class | When |
|---|
400 | Bad request | Malformed JSON, validation failed, business-rule violation |
401 | Unauthorized | Auth missing, malformed, expired, or revoked |
403 | Forbidden | Authenticated but lacking the required scope, role, or whitelisted IP |
404 | Not found | Resource doesn’t exist or is soft-deleted |
405 | Method not allowed | HTTP method not implemented for this route |
409 | Conflict | Uniqueness violation (e.g. duplicate farm name) |
422 | Unprocessable | Semantically valid request but cannot be fulfilled |
429 | Too many requests | Rate limit exceeded |
5xx | Server error | Transient — safe to retry with backoff |
Error code reference
Authentication and authorization
code | Status | Meaning |
|---|
MISSING_API_KEY | 401 | No Authorization header sent |
INVALID_AUTH_FORMAT | 401 | Header is not Bearer <key> |
INVALID_API_KEY_FORMAT | 401 | Key doesn’t match wy_(live|test)_[a-f0-9]{48} |
INVALID_API_KEY | 401 | Key not found or revoked |
INACTIVE_API_KEY | 401 | Key exists but is currently disabled |
EXPIRED_API_KEY | 401 | Key passed its expiresAt timestamp |
UNAUTHORIZED | 401 | Generic auth failure (session-auth surfaces) |
IP_NOT_WHITELISTED | 403 | Request came from an IP not in the key’s allowlist |
INSUFFICIENT_SCOPE | 403 | Key is valid but missing the scope this route requires |
FORBIDDEN | 403 | Authenticated but not authorized for this resource |
AUTH_ERROR | 500 | Auth subsystem failure — retry with backoff |
Resource and validation
code | Status | Meaning |
|---|
NOT_FOUND | 404 | Resource doesn’t exist or has been soft-deleted |
VALIDATION_ERROR | 400 | Request body or query failed schema validation — see details |
INVALID_ID | 400 | Path parameter (e.g. :id) is not a valid UUID |
CONFLICT | 409 | Uniqueness or state-machine violation |
LIMIT_EXCEEDED | 400 | A per-user limit (e.g. 10 API keys) was hit |
Rate limiting
code | Status | Meaning |
|---|
RATE_LIMIT_EXCEEDED | 429 | Per-user sliding-window limit reached. Response carries X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset (ISO 8601) |
Server
code | Status | Meaning |
|---|
INTERNAL_ERROR | 500 | Generic unexpected failure |
SERVICE_UNAVAILABLE | 503 | Downstream dependency unavailable (e.g. AI provider, FX rate source) — fail-open behavior varies per route |
Validation error details
For 400 VALIDATION_ERROR, details is an object whose keys are field names and whose values are arrays of human-readable messages:
{
"error": "Validation failed",
"code": "VALIDATION_ERROR",
"details": {
"name": ["Name is required"],
"totalArea": ["Total area must be greater than 0"],
"country": ["Country is required"]
}
}
Top-level keys correspond to request body fields. Nested fields use dot-notation (boundaries.coordinates).
Insufficient-scope details
For 403 INSUFFICIENT_SCOPE, details tells you exactly what’s needed:
{
"error": "Forbidden",
"code": "INSUFFICIENT_SCOPE",
"message": "Insufficient permissions. Required scope: farms:write",
"details": {
"requiredScope": "farms:write",
"availableScopes": ["farms:read", "crops:read"]
}
}
Recreate the key with the missing scope, or rotate to a key that has it.
Retry strategy by status
| Status | Retry? | How |
|---|
4xx (except 429) | No | Fix the request — retrying the same payload yields the same error |
429 | Yes | Wait until X-RateLimit-Reset (ISO 8601), then retry. See Rate-limit handling |
5xx | Yes | Exponential backoff with jitter, max 3 attempts |
See also