Files
OwnCord/API.md
T
jevb 75b239ecd0 docs: align API.md paths to /api/v1/, fix CLAUDE.md contradiction, mark review resolved
All endpoints in API.md now use /api/v1/ prefix matching
the server router and client. CLAUDE.md no longer
contradicts itself about the base path. CODE_REVIEW.md
updated with ALL RESOLVED status. Also adds Obsidian-Brain
to .gitignore.
2026-03-16 17:11:17 +01:00

8.6 KiB

REST API Spec

Base URL: https://{server}:{port}/api/v1

Auth: session token in cookie session (set on login) or Authorization: Bearer {token} header.

All responses are JSON. Errors return { "error": "CODE", "message": "Human-readable detail" }.


Auth

Method Endpoint Auth Description
POST /api/v1/auth/register None (invite code) Create account
POST /api/v1/auth/login None Login, returns session token
POST /api/v1/auth/logout Yes Invalidate current session
POST /api/v1/auth/verify-totp Partial (2FA) Submit TOTP code

POST /api/v1/auth/register

// Request
{ "username": "alex", "password": "strongpassword", "invite_code": "abc123" }
// Response 201
{ "user": { "id": 1, "username": "alex" }, "token": "session-token" }

POST /api/v1/auth/login

// Request
{ "username": "alex", "password": "strongpassword" }
// Response 200 (no 2FA)
{ "token": "session-token", "requires_2fa": false }
// Response 200 (2FA required)
{ "partial_token": "temp-token", "requires_2fa": true }

Users

Method Endpoint Auth Description
GET /api/v1/users/me Yes Get current user profile
PATCH /api/v1/users/me Yes Update own profile (username, avatar)
PUT /api/v1/users/me/password Yes Change password
POST /api/v1/users/me/totp/enable Yes Start 2FA setup, returns QR
POST /api/v1/users/me/totp/confirm Yes Confirm 2FA with TOTP code
DELETE /api/v1/users/me/totp Yes Disable 2FA
GET /api/v1/users/me/sessions Yes List active sessions
DELETE /api/v1/users/me/sessions/{id} Yes Revoke a session

Channels

Method Endpoint Auth Description
GET /api/v1/channels Yes List all channels user can see
GET /api/v1/channels/{id}/messages Yes Paginated message history
GET /api/v1/channels/{id}/pins Yes Get pinned messages
POST /api/v1/channels/{id}/pins/{msg_id} Yes (mod) Pin a message
DELETE /api/v1/channels/{id}/pins/{msg_id} Yes (mod) Unpin a message

GET /api/v1/channels/{id}/messages

Query params: before (message ID), limit (1-100, default 50)

// Response 200
{
  "messages": [
    {
      "id": 1042,
      "channel_id": 5,
      "user": { "id": 1, "username": "alex", "avatar": "uuid.png" },
      "content": "Hello!",
      "reply_to": null,
      "attachments": [],
      "reactions": [{ "emoji": "👍", "count": 2, "me": true }],
      "pinned": false,
      "edited_at": null,
      "deleted": false,
      "timestamp": "2026-03-14T10:30:00Z"
    }
  ],
  "has_more": true
}

File Uploads

Method Endpoint Auth Description
POST /api/v1/uploads Yes Upload a file (multipart)
GET /api/v1/files/{uuid} Yes Download a file

POST /api/v1/uploads

Multipart form data. Field: file. Max size from server config (default 25MB).

// Response 201
{
  "id": "upload-uuid",
  "filename": "photo.jpg",
  "size": 204800,
  "mime": "image/jpeg",
  "url": "/api/v1/files/upload-uuid"
}

Server validates: magic bytes, rejects executables, strips EXIF, stores with UUID filename.


Method Endpoint Auth Description
GET /api/v1/search Yes Full-text search across accessible channels

Query params: q (search query), channel_id (optional filter), limit (default 25)

// Response 200
{
  "results": [
    {
      "message_id": 1042,
      "channel_id": 5,
      "channel_name": "general",
      "user": { "id": 1, "username": "alex" },
      "content": "...matched text...",
      "timestamp": "2026-03-14T10:30:00Z"
    }
  ]
}

Invites

Method Endpoint Auth Description
GET /api/v1/invites Yes (admin) List all invites
POST /api/v1/invites Yes (manage_invites) Create an invite
DELETE /api/v1/invites/{id} Yes (manage_invites) Revoke an invite

POST /api/v1/invites

// Request
{ "max_uses": 5, "expires_in_hours": 48 }
// Response 201
{
  "id": 1,
  "code": "abc123def",
  "url": "chatserver://invite/abc123def",
  "max_uses": 5,
  "expires_at": "2026-03-16T10:30:00Z"
}

Admin Endpoints (admin panel uses these)

Method Endpoint Auth Description
GET /api/v1/admin/stats Admin Server stats (users, msgs, disk)
GET /api/v1/admin/users Admin List all users with details
PATCH /api/v1/admin/users/{id} Admin Update user (role, ban/unban)
DELETE /api/v1/admin/users/{id}/sessions Admin Force logout a user
POST /api/v1/admin/channels Admin Create channel
PATCH /api/v1/admin/channels/{id} Admin Update channel
DELETE /api/v1/admin/channels/{id} Admin Delete channel
GET /api/v1/admin/audit-log Admin View audit log (paginated)
POST /api/v1/admin/backup Owner Trigger manual backup
GET /api/v1/admin/backups Owner List available backups
POST /api/v1/admin/backups/{id}/restore Owner Restore from backup
GET /api/v1/admin/settings Admin Get server settings
PATCH /api/v1/admin/settings Admin Update server settings
GET /api/v1/admin/update-check Admin Check for new server version
GET /api/v1/admin/updates Admin Check for available server updates
POST /api/v1/admin/updates/apply Owner Apply a server update

GET /api/v1/admin/updates

Check for available server updates.

Authentication: Bearer token (ADMINISTRATOR permission required)

// Response 200
{
  "current": "v1.0.0",
  "latest": "v1.2.0",
  "update_available": true,
  "release_url": "https://github.com/J3vb/OwnCord/releases/tag/v1.2.0",
  "download_url": "https://github.com/J3vb/OwnCord/releases/download/v1.2.0/chatserver.exe",
  "checksum_url": "https://github.com/J3vb/OwnCord/releases/download/v1.2.0/checksums.sha256",
  "release_notes": "## What's Changed\n..."
}

Error responses:

  • 401: Unauthorized (missing/invalid token)
  • 403: Forbidden (not an administrator)
  • 502: Bad Gateway (GitHub API unreachable or returned error)

POST /api/v1/admin/updates/apply

Download and apply a server update. Downloads the new binary, verifies its SHA256 checksum, broadcasts a server_restart WS message, then restarts.

Authentication: Bearer token (Owner role required)

// Response 200
{
  "status": "applying",
  "version": "v1.2.0"
}

Error responses:

  • 401: Unauthorized
  • 403: Forbidden (not Owner)
  • 409: Conflict (server is already up to date)
  • 502: Bad Gateway (download failed, checksum mismatch, or missing release assets)

WebRTC / TURN Credentials

Method Endpoint Auth Description
GET /api/v1/voice/credentials Yes Get time-limited TURN credentials
// Response 200
{
  "ice_servers": [
    { "urls": "stun:server:3478" },
    { "urls": "turn:server:3478", "username": "ts:uid", "credential": "hmac" }
  ],
  "expires_in": 86400
}

Custom Emoji

Method Endpoint Auth Description
GET /api/v1/emoji Yes List all custom emoji
POST /api/v1/emoji Yes (admin) Upload new emoji
DELETE /api/v1/emoji/{id} Yes (admin) Delete emoji

Soundboard

Method Endpoint Auth Description
GET /api/v1/sounds Yes List all soundboard sounds
POST /api/v1/sounds Yes (permission) Upload a sound
DELETE /api/v1/sounds/{id} Yes (admin) Delete a sound

Health Check

Method Endpoint Auth Description
GET /api/v1/health None Returns 200 if server is running
{ "status": "ok", "version": "1.0.0", "uptime": 86400 }

Error Codes

Code HTTP Status Meaning
UNAUTHORIZED 401 Missing or invalid session
FORBIDDEN 403 Insufficient permissions
NOT_FOUND 404 Resource not found
RATE_LIMITED 429 Too many requests (includes retry_after)
INVALID_INPUT 400 Bad request body or params
CONFLICT 409 e.g. username already taken
TOO_LARGE 413 File exceeds upload limit
SERVER_ERROR 500 Internal server error