Skip to navigation

Errors

The error envelope, every error code, and how to tell them apart.
View as Markdown

The envelope

Every failed request returns the same shape:

{
"error": {
"code": "validation_error",
"message": "One or more fields failed validation.",
"details": [
{ "field": "query.to", "message": "Required" }
]
},
"requestId": "0f8fad5b-d9cb-469f-a165-70867728950e"
}

code is a stable identifier — branch on it, not on message, which is written for humans and may be reworded. details is only present on validation errors.

Error codes

CodeStatusWhat it means
bad_request400The request was understood but the parameters make no sense
invalid_api_key401No key, a malformed key, or a key that does not exist
api_key_revoked401The key was revoked, or has expired
unauthorized401Reserved; not currently returned
forbidden403Authenticated, but the plan does not include this feature
player_limit403The project is already at its concurrent-player ceiling
not_found404No such route, or no such record
method_not_allowed405Wrong verb for this path
conflict409Conflicts with the current player state
validation_error422A parameter failed validation
rate_limited429Over quota — see rate limits
internal_error500An unexpected fault
service_unavailable503A dependency is down or timed out

Two statuses fall outside that table because they come from specific endpoints rather than the shared mapping: Minecraft routes return 502 when an upstream service fails, and GET /v1/jobs/{id}/wait returns 504 when the timeout elapsed before the job finished.

Validation errors

A missing or malformed parameter is a 422, and details lists each one. The field is the Zod path joined with a dot, so it reads query.to, path.guildId, or body.volume depending on where the parameter lives.

{
"error": {
"code": "validation_error",
"message": "One or more fields failed validation.",
"details": [
{ "field": "query.amount", "message": "Too big: expected number to be <=5" },
{ "field": "query.type", "message": "Invalid enum value. Expected 'hug', received 'punch2'" }
]
},
"requestId": "0f8fad5b-d9cb-469f-a165-70867728950e"
}

GET /v1/fun/roleplay is the exception: it answers 400 with bad_request for validation failures, because it overrides the global handler. Everything else is 422.

Success envelopes are not uniform

Most endpoints wrap their payload in data, but the wrapper differs by area:

ShapeEndpoints
{ "success": true, "data": ... }Image, Tools, Fun, Translation, Roblox, Minecraft, Holidays
{ "data": ... }Bible, Jobs, Music
{ "error": false, "data": ... }Binary encode and decode — note the flag is named error
No envelopeGET /v1/status

Read the schema in the API reference rather than assuming a shape. The JavaScript SDK hides this: it unwraps data for you and resolves to the inner value.

Request IDs

Every response carries an X-Request-Id header, echoed from your request if you sent one and generated otherwise. The same value appears as requestId in the error body.

Send your own to correlate a failure with your logs:

curl "https://api.aegi.run/v1/status" \
--header "X-Request-Id: order-4821-checkout"

Quote that id when reporting a problem — it is what makes the request findable in the logs.

Handling errors

The SDK turns every non-2xx response into an AegisError:

import { Aegis, AegisError } from 'aegis-api'
try {
await aegis.music.play(guildId, { query: 'lofi' })
} catch (error) {
if (error instanceof AegisError) {
error.status // 403
error.code // 'forbidden'
error.requestId // quote this when asking for help
}
}

There is one error class, not a hierarchy — branch on status or code. See SDK errors for the details.