5033 Studios — AI Integration Guide (llms.txt) ================================================ This file is for AI assistants and developer tools that need to understand the 5033 Studios ecosystem, its SSO system, and its APIs without reading any backend source code. Last reviewed: 2026-08-05. -------------------------------------------------------------------------- SECTION 1: OVERVIEW -------------------------------------------------------------------------- 5033 Studios is a Swiss software studio building a family of small, focused apps that all share one account system. Apps: - account.5033.ch — central account system (SSO), registration, login. - dev.5033.ch — this developer portal: dev account applications, API key management, and this documentation file. - butgi.ch — personal/family budget tracking app. Has a full JSON API. - mind3.li — personal AI inbox (email triage, calendar, alarms). SSO and dashboard shell exist; the inbox/calendar/alarm API is not built yet. - bot3.ch — anonymous public AI chat widget. No accounts, no API, no database. - drop3.ch — file sharing product. Not built yet: static "coming soon" page only, no backend, no database. The 5033 Dev Program lets developers request elevated "dev" status (dev_approved / dev_badge) to build integrations against the apps above that have real APIs (currently: Butgi). -------------------------------------------------------------------------- SECTION 2: HOW TO GET A DEV ACCOUNT -------------------------------------------------------------------------- 1. Log in at https://dev.5033.ch (redirects to the 5033 SSO if needed). 2. Fill out the application form at https://dev.5033.ch/apply.php: - Warum möchtest du einen Dev Account? (required) - Was planst du zu bauen? (required) - Hast du Erfahrung mit APIs? Ja/Nein (+ optional detail text) - Links (optional, up to 5) — GitHub, own website, portfolio, etc. - Checkbox: AGB accepted (required) - Checkbox: data storage consent (required) 3. Submitting sets your status to "pending" and emails the 5033 admin with the full application plus one-click Approve/Reject links. 4. The admin decision is final for that attempt: - Approved → status becomes "approved", dev_badge/dev_approved are set everywhere, you get access to the developer dashboard. - Rejected (1st attempt) → status "rejected_1". You can re-apply after 7 days, with an extra required field explaining what changed. - Rejected (2nd attempt) → status "rejected_2". Permanent — no further applications are possible. 5. After approval, go to https://dev.5033.ch/dashboard.php to: - toggle per-app API access on/off - generate/revoke API keys - read per-app documentation Access can be revoked by 5033 Studios at any time without prior notice — see the AGB at https://dev.5033.ch/agb.php. -------------------------------------------------------------------------- SECTION 3: SSO SYSTEM -------------------------------------------------------------------------- Every 5033 app (including this dev portal) authenticates exclusively through account.5033.ch. There is no per-app password system. Step 1 — Redirect the user to log in: GET https://account.5033.ch/login?client={CLIENT_ID}&redirect_uri={CALLBACK_URL}&state={RANDOM} - client: your registered client id (e.g. "butgi", "mind3", "dev") - redirect_uri: must exactly match the URL registered in SSO_ALLOWED_CLIENTS on account.5033.ch's server — no partial matches. - state: a random value your app generated and stored (e.g. in a short- lived cookie), used to prevent CSRF on the redirect. Verify it matches on callback before doing anything else. Step 2 — account.5033.ch redirects back after login/register: GET {CALLBACK_URL}?code={CODE}&state={STATE} - Verify `state` matches what you generated in Step 1. - `code` is a one-time code, valid ~60 seconds, single-use. Step 3 — Exchange the code server-to-server (never in the browser): POST https://account.5033.ch/api/exchange-code.php Content-Type: application/x-www-form-urlencoded Body: code={CODE}&client_secret={SHARED_SECRET} - client_secret is a shared secret between your app and account.5033.ch, stored server-side only (currently at /var/www/mind3-config/sso-shared-secret.txt on the server, shared by all clients — ask 5033 Studios to add your client to SSO_ALLOWED_CLIENTS before integrating). Response (200 on success): { "valid": true, "user_id": 11, "username": "niels", "email": "niels@5033.ch" } Response (401 on failure): { "valid": false, "error": "invalid_or_expired_code" } On success: create or update a local user row keyed by `user_id` (call it sso_user_id in your own schema), and start your own session — never store account.5033.ch's own session cookie or JWT in your app. Step 4 — Verifying an existing session/token directly (alternative to the code exchange, used e.g. for one-off checks): GET or POST https://account.5033.ch/api/verify-token.php Auth: Authorization: Bearer {token} (or token in POST/GET body, or the account.5033.ch sid_token cookie if you're on a *.5033.ch subdomain) Response (200): { "valid": true, "user_id": 11, "username": "niels", "email": "niels@5033.ch", "credits": 300, "plan": "free", "dev_badge": false } Note: `dev_badge` reflects the dev_badge column on account.5033.ch's own users table — see SECTION 4. How to add a new app as an SSO client: 1. Ask 5033 Studios to add your client id + exact callback URL to SSO_ALLOWED_CLIENTS in the shared account.5033.ch config. 2. Build a callback.php that: reads code+state, verifies state, POSTs to exchange-code.php, upserts a local user row, starts a session. 3. Every subsequent page/API request in your app checks your own local session — never call account.5033.ch on every request. -------------------------------------------------------------------------- SECTION 4: DEV BADGE -------------------------------------------------------------------------- - Column: account.5033.ch `users.dev_badge` (TINYINT(1), default 0). - Set to 1 when a dev application is approved, set to 0 when revoked. - Propagated to each app's own `users.dev_approved` column (Butgi and mind3 currently; bot3 and drop3 have no users table yet, see SECTION 1). - account.5033.ch's verify-token.php response includes `dev_badge` (see SECTION 3) — apps should read it from there, not maintain their own copy as the source of truth (their local dev_approved column is a cache kept in sync by the dev portal, not the origin of truth). - Display rule: show a small "Dev" pill (background #4D9FFF, white text) directly next to the username, only in places where the username is already shown (profile, settings, etc). The badge itself must never be searchable or exposed as a separate lookup/filter. -------------------------------------------------------------------------- SECTION 5: API AUTHENTICATION (for API keys issued by the dev portal) -------------------------------------------------------------------------- - Generate keys at https://dev.5033.ch/dashboard.php. A key is shown in full exactly once, at creation time — only its SHA-256 hash is stored server-side afterwards, so losing a key means generating a new one. - Pass the key as: `Authorization: Bearer {key}` - Keys are currently issued and stored by the dev portal (dev_api_keys table) as the account-level credential for the dev program. Per-endpoint enforcement of these keys on Butgi's own API is on the roadmap — today, Butgi's API is authenticated via the same session-based SSO login used by its own web app (see SECTION 6). -------------------------------------------------------------------------- SECTION 6: BUTGI API -------------------------------------------------------------------------- Base URL: https://butgi.ch Auth: session cookie from the SSO login flow (SECTION 3). State-changing requests (POST/PUT/PATCH/DELETE) also require an X-CSRF-Token header — obtain the token from the logged-in page's `window.BUTGI.csrfToken`. GET /api/accounts.php list accounts (+balance) POST /api/accounts.php create {name, type, color} PUT /api/accounts.php?id={id} update DELETE /api/accounts.php?id={id} delete GET /api/categories.php list categories (?with_summary=1&month=YYYY-MM adds budget/spent/status) POST /api/categories.php create {name, icon, budget_amount, budget_period, warn_threshold, account_id} PUT /api/categories.php?id={id} update DELETE /api/categories.php?id={id} delete GET /api/income.php get {monthly_amount, has_thirteenth, effective_monthly} POST /api/income.php set {monthly_amount, has_thirteenth} GET /api/automations.php list (Normal+ mode only) POST /api/automations.php create {type, name, amount, period, category_id, from_account_id, to_account_id} DELETE /api/automations.php?id={id} delete GET /api/transactions.php list (filters: start, end, category_id, account_id, type, limit) POST /api/transactions.php create {amount, type, category_id, account_id, note, transaction_date, recurring, recurring_period} PUT /api/transactions.php?id={id} update DELETE /api/transactions.php?id={id} delete GET /api/budget.php?filter=day|week|month|year&month=YYYY-MM overview {spent, budget, remaining}, trend_percent (Pro+ mode), categories[] (Pro+ mode only) GET /api/settings.php get profile settings GET /api/settings.php?resource=modules list unlockable feature modules POST /api/settings.php?resource=modules toggle a module {key, enabled} POST /api/settings.php?resource=delete_all account wipe, requires {confirm: "DELETE"} POST /api/settings.php update {theme, accent_color, language, app_mode} GET /api/savings.php list savings goals (Pro+) POST /api/savings.php create {name, target_amount, account_id, target_date} PUT /api/savings.php?id={id} update DELETE /api/savings.php?id={id} delete GET /api/dev/keys.php list your own API keys (requires dev_approved=1) POST /api/dev/keys.php generate {label} DELETE /api/dev/keys.php?id={id} revoke App modes (beginner/normal/pro/dev) gate which features are visible and which fields a request may meaningfully use — see butgi.ch's own includes/auth.php userCan() feature matrix for the authoritative list. -------------------------------------------------------------------------- SECTION 7: STANDARD RESPONSE FORMAT -------------------------------------------------------------------------- Every JSON endpoint across every 5033 app returns exactly this shape: { "success": bool, "data": any, "error": string|null } Common HTTP status codes: 200 — success 401 — not authenticated (no valid session) 403 — authenticated but not permitted (wrong mode, CSRF failure, not an approved dev, etc.) 404 — resource not found / doesn't belong to the current user 405 — method not allowed 422 — validation failed (missing/invalid fields) -------------------------------------------------------------------------- SECTION 8: DATABASE CONVENTIONS -------------------------------------------------------------------------- - Every per-user table has a `user_id` column; every query filters by it. The user_id used is always resolved server-side from the session — never trust one supplied in a request body or query string. - Every app's `users` table has a `dev_approved TINYINT(1) DEFAULT 0` column, kept in sync by the dev portal's badge propagation (SECTION 4). - Currency is always Swiss francs, formatted "CHF 1'234.50" — an apostrophe as the thousands separator, always 2 decimal places. - Prepared statements (PDO) are used for every query, no exceptions. -------------------------------------------------------------------------- SECTION 9: HOW TO CONNECT A NEW APP -------------------------------------------------------------------------- 1. Pick a client id (short, lowercase, e.g. "myapp") and decide your callback URL, e.g. https://myapp.5033.ch/api/auth/callback.php. 2. Ask 5033 Studios to add {client id: callback URL} to SSO_ALLOWED_CLIENTS in account.5033.ch's shared config, and to share the SSO shared secret with your app's server (kept in a file outside the web root, never in client-side code). 3. Build your login entry point: generate a random `state`, store it in a short-lived HttpOnly cookie, redirect to account.5033.ch/login with client/redirect_uri/state (SECTION 3, Step 1). 4. Build your callback.php: verify `state`, POST the `code` to exchange-code.php server-side, upsert a local user row keyed by the returned user_id, start your own app session (SECTION 3, Steps 2-3). 5. On every subsequent request, check your own session — don't call account.5033.ch again per-request. 6. If your app has an admin/dev features, check the local dev_approved column (kept in sync by the dev portal) rather than re-deriving it. 7. If you show usernames anywhere, read `dev_badge` from verify-token.php's response (or your locally cached dev_approved flag) and render the small blue "Dev" pill next to the name (SECTION 4). 8. Add your app's users table to the dev portal's badge propagation (includes/badge.php on dev.5033.ch) so approvals/revocations reach it. 9. Document your endpoints and add a docs/{app}.php page + a new section to this file so other developers and AI assistants can use it too. -------------------------------------------------------------------------- SECTION 10: CONTACT -------------------------------------------------------------------------- Developer portal: https://dev.5033.ch Admin / questions: niels@5033.ch