1 API-Reference
xpltd_admin edited this page 2026-04-03 22:51:34 -06:00

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.

{"status": "ok"}

Auth

POST /api/v1/auth/register

Create account. Requires Turnstile CAPTCHA token (if configured).

{
  "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.

{
  "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.

{
  "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.

{
  "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)

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).

{
  "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.

{
  "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).

{
  "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.

{
  "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).

{
  "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.

{
  "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

{
  "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 page for MCP tool documentation.