Authentication
Authenticate Xenodia API calls with long-term API keys and server-side Bearer headers.
Xenodia public API calls use Bearer authentication.
Authorization: Bearer YOUR_LONG_TERM_KEYKeep API keys on the server. Do not expose a long-term key in browser JavaScript, mobile app bundles, public logs, or agent prompts that may be replayed into untrusted tools.
Base URL
https://api.xenodia.xyzMost endpoints in these docs are shown as full URLs for clarity.
Minimal headers
Content-Type: application/json
Authorization: Bearer YOUR_LONG_TERM_KEYMultipart media uploads should use the form boundary generated by your HTTP client rather than manually setting Content-Type.
Error handling
Clients should treat authentication errors as non-retryable until credentials change.
| Status | Meaning |
|---|---|
401 | Missing, malformed, expired, or invalid credentials. |
403 | Credentials are valid but do not allow the requested action, model, group, or billing mode. |
429 | Rate limit or quota boundary reached. Retry only according to response headers or your own backoff policy. |
Production checklist
- Store keys in a secret manager or encrypted environment variable.
- Use separate keys for local development, staging, and production.
- Rotate keys when developers leave or logs may have exposed credentials.
- Do not log raw request headers.
- Do not let agents create new long-term keys without an owner-approved policy.
Manage API keys
GET /v1/me/api-keys returns keys, the metadata for all keys owned by the authenticated account, including revoked keys. The existing data field remains the latest active key or null. Metadata never includes an existing secret.
| Action | Endpoint | Credential |
|---|---|---|
| Create another key | POST /v1/me/api-keys | Access token |
| Revoke one owned key | DELETE /v1/me/api-keys/{id} | Access token |
| Revoke every active key | DELETE /v1/me/api-keys | Access token |
Creation returns the new secret once and leaves older keys active. To rotate safely, create a replacement, update the integration, then explicitly revoke the old key. If a key is compromised, revoke it immediately. Revocation returns { "ok": true } and takes effect on subsequent authenticated requests. Revoking one key does not affect other keys or browser sessions.
Login sessions, refresh and sign-out
Access tokens and refresh tokens belong to a revocable login session. Send a refresh token only in the JSON body of POST /v1/auth/refresh:
{ "refresh_token": "YOUR_REFRESH_TOKEN" }Each refresh token can be exchanged once. Serialize refresh requests and store the returned access and refresh tokens together. Reusing a consumed token returns 401; do not run overlapping refresh calls. A network timeout may mean the server already exchanged the token. If a retry receives 401, sign in again rather than repeatedly replaying it.
POST /v1/auth/logout accepts the same JSON body and revokes that session family, including access tokens and refresh tokens already produced by rotation. It accepts an unexpired signed refresh token from that family even if it was already exchanged. Wait for { "ok": true } before treating server-side sign-out as complete. Clearing browser storage alone does not revoke a session.
POST /v1/me/sessions/revoke-all, authenticated with an access token, signs out all login sessions for this account, including the caller. Neither sign-out operation revokes API keys; use the key revocation endpoints separately.
Revoked or expired credentials return 401. A banned or inactive account returns 403. After the revocable-session upgrade, older access/refresh tokens without a session identifier (sid) require one fresh sign-in; existing API keys are preserved. Clients should treat tokens as opaque, and respond to 401 by requesting authentication.
Browser tabs that share one login session coordinate refresh and sign-out. A short-lived in-memory handoff lets a duplicate tab adopt a rotated token without replaying the old refresh; long-lived credentials are not stored in localStorage. Separate login sessions stay independent. Legacy tokens without a session ID require a fresh sign-in; the site also rechecks the current session when restoring a page and handles server revocation without waiting for access-token expiry.
Invitation codes apply only to new Google registrations. A stale code cannot block an existing account. If a new registration has an invalid code, edit the code or choose Continue without invitation; this clears both the URL parameter and the saved invitation before retrying.