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