Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.7331.org/llms.txt

Use this file to discover all available pages before exploring further.

The Portal API supports two authentication methods depending on whether you’re a user or a bot. Users authenticate via a platform-delivered code flow. Once verified, a session cookie (psession) is set and used for subsequent requests. All authentication endpoints require the X-API-Key header with the public API key. After login, subsequent requests use the session cookie instead.

Returning User Flow

1

Look up username

Call POST /v1/authentication/lookup with your username. The response includes your linked platforms (Discord, Telegram, etc.) so the client can present login options.
2

Request a login code

Call POST /v1/authentication/request with the chosen platform and platform user ID. A login code is generated.
3

Verify the code

Call POST /v1/authentication/verify with the 8-character code. The request body is just {"code": "..."}.
4

Use the session

The response sets an psession cookie. Include this cookie in all subsequent requests.

New User Flow

New users skip the lookup step (they don’t have a username yet) and go straight to requesting a login code with their platform identity.
1

Request a login code

Call POST /v1/authentication/request with the platform and platform user ID.
2

Verify the code

Call POST /v1/authentication/verify with the 8-character code. The backend automatically creates a new account with a random username (e.g. user_a1b2c3d4).
3

Change username (optional)

Call POST /v1/users/me/update to set a custom username.

Example (Returning User)

# Step 1: Look up username to get linked platforms
curl -X POST https://portal-api.7331.org/v1/authentication/lookup \
  -H "Content-Type: application/json" \
  -H "X-API-Key: your-public-api-key" \
  -d '{"username": "championoftheworld"}'

# Step 2: Request a login code via a linked platform
curl -X POST https://portal-api.7331.org/v1/authentication/request \
  -H "Content-Type: application/json" \
  -H "X-API-Key: your-public-api-key" \
  -d '{"platform": "discord", "platform_user_id": "123456789012345678"}'

# Step 3: Verify the code
curl -X POST https://portal-api.7331.org/v1/authentication/verify \
  -H "Content-Type: application/json" \
  -H "X-API-Key: your-public-api-key" \
  -d '{"code": "ABCD1234"}'

# Step 4: Use authenticated endpoints
curl https://portal-api.7331.org/v1/users/me \
  -b "psession=YOUR_SESSION"

Bot-Initiated Flow (Existing Users Only)

Returning users can skip the web-initiated step entirely. The bot generates the code directly via its API key and DMs it to the user.
1

User requests login via bot

User types /login in Discord or Telegram.
2

Bot generates the code

Bot calls POST /v1/authentication/bot/send-code with the user’s platform identity. The code is returned directly in the response.
3

Bot DMs the code

Bot sends the code to the user via platform DM.
4

User enters the code

User visits the frontend, clicks “I already have a code”, and enters the 8-character code.
This flow only works for users who already have an account. Unknown platform identities receive a 404 response — the bot should direct them to sign up on the website first.

Bot Authentication (API Key)

Bots authenticate using an API key passed in the X-API-Key header. API keys are generated when a bot is registered via the admin panel.

Usage

curl https://portal-api.7331.org/v1/bot/me \
  -H "X-API-Key: your-bot-api-key"
API keys are only shown once when a bot is registered. Store them securely.

Admin Authentication

Admin users authenticate through the same login flow as regular users. There are no separate admin auth endpoints — permission checks happen per-request via session cookies. When an admin or owner logs in, the session cookie is automatically configured with a shorter TTL:
  • Cookie TTL: 1 day (vs 30 days for regular users)
All session cookies use SameSite=none, Secure=true, and domain .7331.org to work across subdomains (portal-api, portal-ws, portal). Admin endpoints verify the caller’s permission level on every request. There is no separate “admin session” — the same psession cookie is used for all authenticated requests.

Session Limits

Each user may have at most 5 active sessions at a time (MAX_SESSIONS_PER_USER=5). Logging in beyond that evicts the oldest existing session using a per-user Redis sorted set index (O(log N), no keyspace scan). The evicted device loses its WebSocket connection and its psession cookie becomes invalid. E2EE and multi-device: Each session owns its own E2EE keypair (keyed on the psession cookie). Chat keys are fanned out to every active session of each recipient, so a user can be online on multiple devices simultaneously without any sync dance.

Rate Limits

Web-initiated codes: Each IP address can have at most 5 pending login codes at a time. This prevents abuse where an attacker could lock up many accounts by generating codes from a single IP (codes are IP-bound, so the real user from a different IP cannot verify them). If you exceed this limit, the API returns 429 Too Many Requests. Wait for existing codes to expire (10 minutes) or verify them to free up slots. Bot-initiated codes: No per-IP rate limit (the bot has no web client IP). Rate limiting is handled by the bot API key rate limit (600/minute). Each platform identity can only have one active code at a time — repeated requests return the same code.