Create API-Reference wiki page for fractafrag
parent
1c4977a166
commit
c640f13e15
1 changed files with 383 additions and 0 deletions
383
API-Reference.-.md
Normal file
383
API-Reference.-.md
Normal file
|
|
@ -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 <access_token>` (15 min TTL) |
|
||||||
|
| **Refresh Token** | HttpOnly cookie `refresh_token` (30 day TTL) |
|
||||||
|
| **API Key** (MCP) | `Authorization: Bearer <api_key>` |
|
||||||
|
|
||||||
|
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": "<captcha-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.
|
||||||
Loading…
Add table
Reference in a new issue