From c640f13e15cd3503852bc9785c55231c4d11b9fa Mon Sep 17 00:00:00 2001 From: xpltd_admin Date: Fri, 3 Apr 2026 22:51:34 -0600 Subject: [PATCH] Create API-Reference wiki page for fractafrag --- API-Reference.-.md | 383 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 383 insertions(+) create mode 100644 API-Reference.-.md diff --git a/API-Reference.-.md b/API-Reference.-.md new file mode 100644 index 0000000..4cdd3ca --- /dev/null +++ b/API-Reference.-.md @@ -0,0 +1,383 @@ +# API Reference + +| Meta | Value | +|------|-------| +| **Repo** | `xpltdco/fractafrag` | +| **Page** | `API-Reference` | +| **Audience** | developers, agents | +| **Last Updated** | 2026-04-04 | +| **Status** | current | + +## Base URL + +``` +https://fractafrag.xpltd.co/api/v1 +``` + +Local development: `http://localhost/api/v1` or `http://localhost:8000/api/v1` + +Interactive docs: `/api/docs` (Swagger) or `/api/redoc` (ReDoc) + +## Authentication + +JWT-based with access + refresh tokens. + +| Method | Details | +|--------|---------| +| **Access Token** | `Authorization: Bearer ` (15 min TTL) | +| **Refresh Token** | HttpOnly cookie `refresh_token` (30 day TTL) | +| **API Key** (MCP) | `Authorization: Bearer ` | + +Some endpoints work without auth (feed, browse shaders). Auth-required endpoints return 401 if no valid token. + +--- + +## Health + +### `GET /health` + +Liveness check. No authentication. + +```json +{"status": "ok"} +``` + +--- + +## Auth + +### `POST /api/v1/auth/register` + +Create account. Requires Turnstile CAPTCHA token (if configured). + +```json +{ + "username": "artist42", + "email": "artist@example.com", + "password": "securePassword123", + "turnstile_token": "" +} +``` + +Returns: access token + sets refresh cookie. + +### `POST /api/v1/auth/login` + +Sign in with username/email + password. + +```json +{ + "username": "artist42", + "password": "securePassword123" +} +``` + +Returns: `{ access_token, token_type, user: {...} }` + sets HttpOnly refresh cookie. + +### `POST /api/v1/auth/refresh` + +Exchange refresh token (from cookie) for new access token. Old refresh token is blocklisted. + +### `POST /api/v1/auth/logout` + +Blocklist current refresh token in Redis. + +--- + +## Shaders + +### `GET /api/v1/shaders` + +List/search public published shaders. + +| Param | Type | Default | Description | +|-------|------|---------|-------------| +| `q` | string | — | Search by title (trigram) | +| `tags` | string | — | Comma-separated tag filter | +| `shader_type` | string | — | `2d`, `3d`, `audio-reactive` | +| `system` | boolean | — | Filter system/curated shaders | +| `sort` | string | `trending` | `trending`, `new`, `top` | +| `limit` | int | 20 | Results per page | +| `offset` | int | 0 | Pagination offset | + +### `GET /api/v1/shaders/mine` + +List authenticated user's shaders (drafts, published, archived). Accepts `status` filter. + +### `GET /api/v1/shaders/{shader_id}` + +Get full shader details including GLSL source. Increments `view_count`. + +### `GET /api/v1/shaders/{shader_id}/versions` + +List version history for a shader. + +### `GET /api/v1/shaders/{shader_id}/versions/{version_number}` + +Get GLSL code and metadata for a specific version. + +### `POST /api/v1/shaders` + +Create a new shader. Requires auth. + +```json +{ + "title": "Neon Pulse", + "glsl_code": "void mainImage(out vec4 fragColor, in vec2 fragCoord) { ... }", + "description": "A pulsing neon effect", + "tags": ["neon", "pulse", "glow"], + "shader_type": "2d", + "status": "published" +} +``` + +- Validates GLSL syntax before saving +- Free tier: 5 published shaders/month rate limit +- Enqueues render task if published +- Returns 422 with GLSL errors/warnings on validation failure + +### `PUT /api/v1/shaders/{shader_id}` + +Update a shader. Creates a new version snapshot if code/metadata changed. Re-renders if published. + +```json +{ + "glsl_code": "...", + "title": "Neon Pulse v2", + "change_note": "added color cycling" +} +``` + +### `DELETE /api/v1/shaders/{shader_id}` + +Delete a shader (cascades to versions, votes, events). + +### `POST /api/v1/shaders/{shader_id}/fork` + +Fork a shader. Creates a draft copy linked to the original. + +### `POST /api/v1/shaders/{shader_id}/versions/{version_number}/restore` + +Restore shader to a previous version (creates new version snapshot). + +--- + +## Feed + +### `GET /api/v1/feed` + +Main personalized feed. + +| Param | Type | Default | Description | +|-------|------|---------|-------------| +| `limit` | int | 20 | Results per page | +| `offset` | int | 0 | Pagination offset | + +- **Authenticated:** Tag affinity (from votes + dwell) + recency + score + 10% randomness +- **Anonymous:** Score + recency + 10% randomness +- Excludes shaders user has already viewed (>30 days ago) + +### `GET /api/v1/feed/trending` + +Pure score-ranked (Wilson score + time decay). + +### `GET /api/v1/feed/new` + +Newest shaders first. + +### `GET /api/v1/feed/similar/{shader_id}` + +Tag-overlap-based similar shader recommendations. + +### `POST /api/v1/feed/dwell` + +Report dwell time (used for engagement tracking and tag affinity building). + +```json +{ + "shader_id": "uuid", + "dwell_secs": 15.5, + "session_id": "anonymous-session-id" +} +``` + +--- + +## Votes + +### `POST /api/v1/shaders/{shader_id}/vote` + +Cast or change vote. Recalculates shader hot score. + +```json +{ + "value": 1 +} +``` + +Values: `1` (upvote), `-1` (downvote) + +### `DELETE /api/v1/shaders/{shader_id}/vote` + +Remove vote. Recalculates score. + +### `POST /api/v1/shaders/{shader_id}/replay` + +Report a shader replay event (engagement signal). + +--- + +## Desires (Bounties) + +### `GET /api/v1/desires` + +List open bounties sorted by heat_score. + +| Param | Type | Default | Description | +|-------|------|---------|-------------| +| `status` | string | `open` | Filter by status | +| `min_heat` | float | 0 | Minimum heat score | +| `limit` | int | 20 | Results per page | +| `offset` | int | 0 | Pagination offset | + +### `GET /api/v1/desires/{desire_id}` + +Get single desire with cluster context (cluster_count, similar desires). + +### `POST /api/v1/desires` + +Create a bounty request. Requires auth (Pro+ tier). + +```json +{ + "prompt_text": "A shader that looks like northern lights reflecting on water", + "style_hints": {"color_temp": "cool", "motion_type": "flowing"}, + "tip_amount_cents": 500 +} +``` + +Enqueues async embedding + clustering task. + +### `POST /api/v1/desires/{desire_id}/fulfill` + +Mark a desire as fulfilled by linking to a published shader. + +```json +{ + "shader_id": "uuid-of-published-shader" +} +``` + +### `POST /api/v1/desires/{desire_id}/tip` + +Add tip to bounty (501 — coming in M4). + +--- + +## Users + +### `GET /api/v1/users/{username}` + +Public user profile. + +### `GET /api/v1/me` + +Current authenticated user details. + +### `PUT /api/v1/me` + +Update profile (username, email — uniqueness enforced). + +### `PUT /api/v1/me/ai-keys` + +Store encrypted BYOK provider keys (Pro+ only). + +```json +{ + "provider": "anthropic", + "key": "sk-ant-..." +} +``` + +### `GET /api/v1/me/ai-keys` + +List configured BYOK providers (never returns actual key values). + +--- + +## API Keys (MCP) + +### `GET /api/v1/me/api-keys` + +List user's active API keys (prefix, name, trust_tier, rate_limit). + +### `POST /api/v1/me/api-keys` + +Create API key (Pro+ only). Returns full key once — store it, it can't be retrieved later. + +```json +{ + "name": "My Claude Agent" +} +``` + +Response: `{ id, key: "ff_key_...", prefix, name, trust_tier, rate_limit_per_hour }` + +### `DELETE /api/v1/me/api-keys/{key_id}` + +Revoke an API key (soft delete with `revoked_at` timestamp). + +--- + +## AI Generation (M5 — Stub) + +### `POST /api/v1/generate` + +Start AI shader generation. Returns 501 (Not Implemented). + +### `GET /api/v1/generate/status/{job_id}` + +Poll generation status. Returns 501. + +### `GET /api/v1/generate/credits` + +Check remaining AI credits. + +--- + +## Payments (M4 — Stub) + +All payment endpoints return 501 (Not Implemented): + +- `POST /api/v1/payments/checkout` +- `POST /api/v1/payments/webhook` +- `GET /api/v1/payments/portal` +- `POST /api/v1/payments/credits` +- `POST /api/v1/payments/connect/onboard` + +--- + +## Error Format + +```json +{ + "detail": "Shader not found" +} +``` + +| Status | Meaning | +|--------|---------| +| 400 | Validation error, CAPTCHA failure | +| 401 | Missing or invalid JWT | +| 403 | Insufficient role or subscription tier | +| 404 | Resource not found | +| 409 | Conflict (duplicate username, email, vote) | +| 422 | GLSL validation failure (includes error details) | +| 429 | Rate limit exceeded (free tier: 5 shaders/month) | +| 501 | Feature not yet implemented (M4/M5 stubs) | + +--- + +## WebSocket / MCP + +The MCP server runs on a separate endpoint (`/mcp/*`) with its own tool interface for AI agents. See the [Agent Context](Agent-Context) page for MCP tool documentation. \ No newline at end of file