Skip to navigation

Authentication

API keys, and the one endpoint that does not need one.
View as Markdown

Sending the key

Aegis authenticates with an API key in the Authorization header. There is no other mechanism, and no query parameter alternative for regular endpoints.

curl "https://api.aegi.run/v1/status" \
--header "Authorization: Bearer aegis.3f9a1c8e5b7d2049..."

The Bearer scheme is matched case-insensitively, so bearer and BEARER work just as well.

Keys are sent in a header rather than a query string on purpose — query strings end up in access logs and browser history. The one exception is the events socket, where a ?key= fallback exists because browsers cannot set headers on a WebSocket handshake.

Key format

A key is the literal prefix aegis. followed by exactly 64 lowercase hex characters — 32 random bytes.

aegis.[0-9a-f]{64}

Anything else is rejected as malformed before Aegis touches the database. The prefix is what lets you identify a key in a list without exposing it; only the first eight hex characters are ever stored in the clear.

Keys are stored as a SHA-256 digest. The plaintext is displayed once, at creation, and cannot be retrieved afterwards.

Managing keys

Keys belong to a project, and a project is what rate limits and billing attach to. A project holds up to 25 active keys at a time, so you can give each of your bots its own and revoke one without touching the rest.

Create, name, and revoke keys from aegi.run, or attach one to a Discord bot so the Music API knows which bot to play as.

The one public endpoint

GET /v1/status is the only endpoint that answers without a key:

curl "https://api.aegi.run/v1/status"
{
"status": "ok",
"timestamp": "2026-02-09T14:12:00.000Z",
"uptime": 48213.4,
"version": "1.0.0",
"environment": "production"
}

It is deliberately unauthenticated so uptime monitors can reach it. Because public paths skip rate limiting entirely, this response carries no X-RateLimit-* headers.

Linking a key to a bot

The Music API acts as a Discord bot, and it works out which one from the key rather than from the request. A key with no bot attached gets:

{
"error": {
"code": "forbidden",
"message": "This API key is not linked to a bot. Link it to one to use the music API."
},
"requestId": "0f8fad5b-d9cb-469f-a165-70867728950e"
}

Every other feature works with an unlinked key, so you only need to link one if you are building a music bot.

When a key is rejected

All four failures answer 401 with the standard error envelope. They are distinguished by error.code and the message:

Situationerror.codeMessage
Header missing, or not aegis. + 64 hexinvalid_api_keyProvide your key as "Authorization: Bearer aegis.<key>".
Well-formed, but no such keyinvalid_api_keyThat key does not exist.
Revoked from the dashboardapi_key_revokedThat key revoked.
Past its expiryapi_key_revokedThat key expired.

Revoked and expired keys are reported separately from invalid ones on purpose, so you can tell “rotate this key” apart from “you sent it wrong”.