Errors
All Management API errors follow one consistent JSON envelope: message, error_code, and detail. Knowing how to interpret each field helps you surface actionable feedback to your users and react appropriately in automation.
Response Envelope
Error object
{
"message": "Permission denied",
"error_code": "permission_denied",
"detail": null
}
- Name
message- Type
- string
- Description
Human-readable description. Use for logs or user-facing copy.
- Name
error_code- Type
- string
- Description
Stable machine-readable code. Rely on this field for branching.
- Name
detail- Type
- object | array | null
- Description
Optional extra context. Validation errors populate this field with field-level issues; most other errors return
null.
HTTP Status Codes
| Status | Typical Meaning | Example error_code |
|---|---|---|
| 400 Bad Request | Malformed JSON or unsupported payload | json_parse_error |
| 401 Unauthorized | Missing / invalid auth, expired token, or invalid API key | authentication_failed |
| 403 Forbidden | Authenticated but lacks permissions (role mismatch) | permission_denied |
| 404 Not Found | Environment, folder, resource, etc. does not exist or you cannot access it | environment_not_found, resource_not_found, locale_not_found |
| 405 Method Not Allowed | Wrong HTTP verb for the endpoint | method_not_allowed |
| 422 Unprocessable Content | Request failed validation or business rules (includes plan limits and quota violations) | validation_error, plan_limit_exceeded, trailing_slash_required, protected_environment_cannot_be_deleted |
| 429 Too Many Requests | Plan limits or request-unit throttling were hit | plan_limit_exceeded, rate_limit_exceeded |
| 500 Internal Server Error | Unexpected backend error | internal_server_error |
Endpoints often expose specific codes such as protected_environment_cannot_be_deleted, api_prefix_exists, or folder_already_connected_to_api. The HTTP status always matches the error type even when the code changes.
Validation Errors (422)
Field-level validation issues set error_code to validation_error and populate detail with an array of issues:
Validation error
{
"message": "Invalid data was provided",
"error_code": "validation_error",
"detail": [
{
"type": "string_too_short",
"loc": ["name"],
"msg": "String should have at least 1 character",
"input": ""
}
]
}
- Name
type- Type
- string
- Description
Error classifier (e.g.,
string_too_short,value_error).
- Name
loc- Type
- array
- Description
Location of the invalid field. Nested fields appear as multiple entries, such as
["fields", 0, "id"].
- Name
msg- Type
- string
- Description
Readable description that can be shown to end users.
- Name
input- Type
- any
- Description
Value that failed validation.
- Name
ctx- Type
- object | null
- Description
Optional metadata (for example,
{"min_length": 1}).
Endpoint-Specific Errors
Business rule violations use dedicated error codes so you can react explicitly:
Endpoint-specific error
{
"message": "Protected environment cannot be deleted",
"error_code": "protected_environment_cannot_be_deleted",
"detail": null
}
Examples include environment_toggle_error, too_many_versions, or folder_limit_reached. These codes indicate business constraints specific to the endpoint and are returned with detail: null.
Trailing Slash Requirement
All Management API URLs must end with a trailing slash (/). For GET requests, a missing slash results in an automatic 301 redirect. For all other HTTP methods (POST, PUT, PATCH, DELETE), the API returns a 422 error:
Trailing slash error
{
"message": "URL must end with a trailing slash.",
"error_code": "trailing_slash_required",
"detail": null
}
Always ensure your request URLs include a trailing slash to avoid this error.
Handling Patterns
import axios from 'axios';
async function createFolder(payload) {
try {
const { data } = await axios.post('https://api.foxnose.net/v1/7c9h4pwu/folders/', payload);
return data;
} catch (error) {
if (!error.response) throw error;
const { status, data } = error.response;
if (status === 422 && data.error_code === 'validation_error') {
return data.detail.map((item) => ({
field: item.loc.join('.'),
message: item.msg,
}));
}
if (data.error_code === 'permission_denied') {
throw new Error('You lack access to this environment.');
}
throw new Error(data.message);
}
}