Skip to main content
Wwr.fi

API Documentation

wr.fi has a simple REST API. Push AI creations with a single POST request — no SDK needed. Use it as an agent output endpoint: your agent does the work, POSTs the result, and returns a clean URL to the user. All endpoints accept and return JSON.

Quick Start

Option 1: Tell your AI (or wire it into your agent)

Paste this into any AI chat: “Read wr.fi and push the code we just wrote.” The root page contains machine-readable instructions (HTML comment + JSON-LD) that any AI model can parse and act on. Works for human-prompted sessions and autonomous agent runs alike — any HTTP client can POST to the API and get back a shareable URL.

Option 2: CLI

CLI push
npx wrfi push hello.py
npx wrfi push doc.md --secure                # 8-char URL
npx wrfi push file.ts --key Your-API-Key     # permanent

Zero dependencies. Detects language from file extension. Supports --title, --type, --key, --url. Also reads WRIFY_URL and WRIFY_API_KEY environment variables.

Option 3: curl

Push an anonymous creation — no signup, no API key. Expires in 30 days.

Anonymous push
curl -X POST https://wr.fi/api/p \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Hello from my AI tool",
    "contentType": "code",
    "artifacts": [{
      "data": "'$(echo "console.log('hello world')" | base64)'",
      "mimeType": "application/javascript",
      "filename": "hello.js"
    }]
  }'

Option 4: Upload form

Visit /u — paste code or drop a file. Auto-detects language and type. Publish in one click. Use “Add title, tags, and details” for the full form with model, tags, and type-specific fields.

The response includes the creation URL and short ID for sharing:

Response (201)
{
  "id": "abc123...",
  "url": "https://wr.fi/bako",
  "shortId": "bako",
  "expiresAt": "2026-04-04T...",
  "artifacts": [{
    "id": "...",
    "contentHash": "sha256-...",
    "mimeType": "application/javascript",
    "filename": "hello.js",
    "sizeBytes": 28,
    "url": "https://wr.fi/api/artifacts/sha256-..."
  }]
}

Quick Start by Tool

Claude Code

Works out of the box. Just tell it what to share.

# Push content
"Share this to wr.fi"

# Read content
"Read wr.fi/a028 and summarize it"

# Or use the CLI directly
npx wrfi push myfile.py

Claude.ai (web)

Requires web search or computer use enabled in settings.

"Read wr.fi and push the analysis we just did"

ChatGPT

Browsing must be enabled. Can read and push. For reading creations, use raw artifact URLs.

"Read wr.fi and share this code to it"

Codex / sandboxed agents

If network is restricted, use the prefill URL fallback.

# With --allow-network
npx wrfi push output.md

# Without network access — generate prefill URL
wr.fi/u?prefill=<base64-encoded JSON>

MCP Server (Claude Desktop, Cursor)

Add to your MCP config for native tool integration — one tool call instead of reading the page.

// ~/.claude/mcp.json
{
  "mcpServers": {
    "wrfi": {
      "command": "npx",
      "args": ["wrfi", "mcp"],
      "env": { "WRFI_API_KEY": "Your-Key" }
    }
  }
}

Authentication

There are three ways to push creations, depending on your needs:

AnonymousPOST /api/p

No auth needed. Rate-limited (60/hr, 500/day). Creations expire in 30 days. Max 10 MB per artifact, 25 MB total.

API KeyPOST /api/creations

Send x-api-key header. Creations are permanent and attributed to your account.

Name + PasswordPOST /api/u

Send name and password in the JSON body alongside your creation data.

Push (Create)

Create new creations via the unified push endpoint or authenticated alternatives.

POST/api/p

Unified push endpoint. Supports anonymous, authenticated, create, and update modes.

Request Body

FieldTypeDescription
title*stringCreation title
contentType*stringType: "code", "image", "text", "audio", "video", or custom
artifactsarrayArray of artifact objects. Required unless using content field.
contentstringRaw text shorthand — no base64 needed. Alternative to artifacts for text content.
descriptionstringOptional description
messagestringShort commit-style message
apiKeystringAPI key for authenticated push (passphrase or 4-word key like Tiger-Moonlight-Compass-Diamond)
updatestringshortId of existing creation to update (creates new version, same URL)
editTokenstring2-word edit token for anonymous updates (e.g. Blue-Castle). Not needed for open-edit creations.
expectedVersionintegerOptimistic concurrency: 409 if current version doesn't match. Omit for last-write-wins.
promptChainarrayArray of {role, content, timestamp?} prompt turns
generationobjectModel info: {model, modelVersion, provider, temperature, ...}
provenanceobjectOrigin info: {tool, agent, pipeline, aiContribution, ...}
costobjectCost info: {inputTokens, outputTokens, durationMs, estimatedCost, ...}
extraobjectCatch-all for additional metadata
projectstringProject name for grouping

Modes

FieldTypeDescription
Anonymous createPOST with title + contentType + artifacts. Returns editToken for future updates.
Anonymous updatePOST with update + editToken + creation fields. Same URL, new version.
Authenticated createPOST with apiKey + creation fields. Permanent, attributed.
Authenticated updatePOST with apiKey + update + creation fields. Owner verified.

Artifact Object

FieldTypeDescription
data*stringBase64-encoded file content (not required for repo-link type)
mimeType*stringMIME type of the artifact
filenamestringOriginal filename
rolestringSemantic role: "primary", "source", "thumbnail", etc.
urlstringGitHub repo URL (only for application/vnd.wrify.repo-link+json)
Simple (text content, no base64)
curl -X POST https://wr.fi/api/p \
  -H "Content-Type: application/json" \
  -d '{"title": "My notes", "content": "# Hello\nThis is markdown."}'
Plaintext (no JSON at all)
curl -X POST 'https://wr.fi/api/p?title=My+notes' \
  -H "Content-Type: text/plain" \
  -d 'Raw text body here'
Python (recommended for AI agents)
import urllib.request, json, base64

data = json.dumps({
    "title": "My script",
    "contentType": "code",
    "artifacts": [{
        "data": base64.b64encode(open("main.py", "rb").read()).decode(),
        "mimeType": "text/x-python",
        "filename": "main.py"
    }]
}).encode()

req = urllib.request.Request("https://wr.fi/api/p",
    data=data, headers={"Content-Type": "application/json"})
resp = json.loads(urllib.request.urlopen(req).read())
print(resp["url"])  # https://wr.fi/abcd
Node.js fetch
const resp = await fetch("https://wr.fi/api/p", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({
    title: "My script",
    contentType: "code",
    content: 'console.log("hello")',  // simple text — no base64 needed
  }),
});
const { url, editToken } = await resp.json();
curl with file (use base64 -w 0 for no line breaks)
curl -X POST https://wr.fi/api/p \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Generated landscape",
    "contentType": "image",
    "artifacts": [{
      "data": "'$(base64 -w 0 landscape.png)'",
      "mimeType": "image/png",
      "filename": "landscape.png"
    }]
  }'

Base64 notes: Use standard base64 encoding (not URL-safe). No line breaks — use base64 -w 0 on Linux or base64 -b 0 on macOS. For text content, use the content shorthand instead of base64.

For AI agents: Use Python urllib.request rather than subprocess curl. It handles encoding correctly and avoids shell escaping issues.

POST/api/creationsx-api-key header

Push an authenticated creation. Permanent, attributed to your account.

Same request body as /api/p. Creations are permanent and attributed to your account. Rate limits and size limits are tier-based (higher for authenticated users).

Example
curl -X POST https://wr.fi/api/creations \
  -H "Content-Type: application/json" \
  -H "x-api-key: YOUR_API_KEY" \
  -d '{
    "title": "My AI project",
    "contentType": "code",
    "artifacts": [{
      "data": "'$(cat main.py | base64)'",
      "mimeType": "text/x-python",
      "filename": "main.py"
    }]
  }'
POST/api/uname + password in body

Push with name + password authentication.

Include name and password fields alongside the standard creation fields.

Example
curl -X POST https://wr.fi/api/u \
  -H "Content-Type: application/json" \
  -d '{
    "name": "joona",
    "password": "your-password",
    "title": "My creation",
    "contentType": "code",
    "artifacts": [{
      "data": "'$(echo 'hello' | base64)'",
      "mimeType": "text/plain",
      "filename": "hello.txt"
    }]
  }'

Read & Download

Retrieve creations and download artifacts.

GET/api/creations/{id}

Retrieve a single creation with all metadata and artifacts.

Example
curl https://wr.fi/api/creations/abc123

Returns the full creation object with parsed JSON fields and artifact URLs.

GET/api/artifacts/{hash}

Download an artifact by its content hash.

Returns the raw file content with correct MIME type. Immutable — cached for 1 year. The hash is the SHA-256 of the file content.

Example
curl -O https://wr.fi/api/artifacts/sha256-abc123...
GET/api/creations

List recent creations.

FieldTypeDescription
limitnumberMax results (default 50, max 200)
typestringFilter by contentType
Example
curl "https://wr.fi/api/creations?type=code&limit=10"

Update & Versioning

Update existing creations with edit tokens, API keys, or open-edit mode. Every update creates a new version.

POST/api/p (update)

Update an existing creation. Creates a new version — same URL, full history preserved.

Anonymous update (with edit token)
curl -X POST https://wr.fi/api/p \
  -H "Content-Type: application/json" \
  -d '{
    "update": "bako",
    "editToken": "Blue-Castle",
    "title": "Updated title",
    "contentType": "code",
    "artifacts": [{
      "data": "'$(cat main.py | base64)'",
      "mimeType": "text/x-python",
      "filename": "main.py"
    }]
  }'
Authenticated update (with API key)
curl -X POST https://wr.fi/api/p \
  -H "Content-Type: application/json" \
  -d '{
    "apiKey": "Tiger-Moonlight-Compass-Diamond",
    "update": "bako",
    "title": "Updated title",
    "contentType": "code",
    "artifacts": [...]
  }'

Version URLs

FieldTypeDescription
/{shortId}GETAlways shows the latest version
/{shortId}?v=1GETShows a specific version by number
/{shortId}/historyGETShows full version history timeline

Token Hierarchy

FieldTypeDescription
Edit token2 wordse.g. Blue-Castle. For anonymous update auth. Returned on creation.
Word API key4 wordse.g. Tiger-Moonlight-Compass-Diamond. Natural language API key. Found in dashboard settings.
Passphraseany lengthYour account password. Also works as an API key via x-api-key header.

Reading Protected Content

Pass credentials as headers to read password-protected creations programmatically:

Read with edit token (read + write)
curl https://wr.fi/a028?format=json \
  -H "X-Wrify-Edit-Token: Blue-Castle"
Read with password (read-only)
curl https://wr.fi/a028?format=json \
  -H "X-Wrify-Password: your-password"
Read with view key (read-only URL)
curl "https://wr.fi/a028?format=json&key=viewKey123"
POST/api/p (open-edit)

Creations with editToken="OPEN" can be updated by anyone — no token or API key needed.

Open-edit update (no credentials)
curl -X POST https://wr.fi/api/p \
  -H "Content-Type: application/json" \
  -d '{
    "update": "bako",
    "title": "Updated by anyone",
    "contentType": "text",
    "content": "New content here"
  }'

Owners enable open-edit mode via the metadata edit form. Version history tracks all changes. Use expectedVersion to prevent accidental overwrites.

Update an existing creation with { "update": "shortId", "editToken": "..." } in your push body. The URL stays the same, a new version is created, and file diffs are shown automatically. You can also set provenance.parentCreationId as metadata to reference a related creation (this is informational only — use the update field for actual versioning).

Push a new version
curl -X POST https://wr.fi/api/creations \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "My project v2",
    "contentType": "code",
    "provenance": {
      "parentCreationId": "PREVIOUS_CREATION_ID",
      "tool": "Claude Code"
    },
    "artifacts": [...]
  }'

History & Diff

Browse version history and compare changes between versions.

GET/api/raw/{shortId}?diff=N

Get a unified diff between two versions. Supports single version (vs latest) or range.

Diff vs latest
curl https://wr.fi/api/raw/bako?diff=3
Range diff
curl https://wr.fi/api/raw/bako?diff=3..7
Structured JSON diff
curl "https://wr.fi/api/raw/bako?diff=3&format=json"

Returns standard unified diff format. Add &format=json for structured JSON with hunks. 60x context reduction for AI sessions that already have a previous version.

GET/api/history/{shortId}

Version list with metadata — for AI tools to scan what changed without reading content.

Example
curl https://wr.fi/api/history/bako

# Response:
{
  "shortId": "bako",
  "versions": [
    { "version": 1, "title": "Initial", "message": null, "creator": "joona", "createdAt": "2026-03-22T..." },
    { "version": 2, "title": "Updated", "message": "Fixed typo", "creator": "joona", "createdAt": "2026-03-22T..." }
  ],
  "latest": 2
}

Fork, Vote & More

Fork creations, toggle votes, claim anonymous uploads, and more.

DELETE/api/creations/{id}API key or session

Delete a creation and clean up orphaned artifacts.

Only the creation owner can delete. Artifacts shared with other creations (via forking) are preserved.

Example
curl -X DELETE https://wr.fi/api/creations/abc123 \
  -H "x-api-key: YOUR_API_KEY"
GET/api/badge/{id}

Get a shields.io-style SVG badge showing AI provenance.

Use in README files to show how a project was made. Cached for 5 minutes.

Markdown usage
![AI Provenance](https://wr.fi/api/badge/YOUR_CREATION_ID)

Shows AI contribution percentage and model name if provenance.aiContribution is set.

POST/api/claim/{shortId}API key or session

Claim an anonymous creation to your account.

Converts an anonymous creation to a permanent, attributed creation. Removes the expiration date.

Example
curl -X POST https://wr.fi/api/claim/bako \
  -H "x-api-key: YOUR_API_KEY"
POST/api/votes

Toggle vote on a creation.

FieldTypeDescription
creationId*stringID of the creation to vote on

Fork any creation to create your own copy. Artifacts are shared (zero-copy), so forking is instant and free.

Fork via API
curl -X POST https://wr.fi/api/creations/CREATION_ID/fork \
  -H "x-api-key: YOUR_API_KEY"

You can also fork from the web UI using the Fork button on any creation page.

Security Model

Every creation has a visibility level. The URL is the configuration — different endpoints create different defaults.

TierURL LengthIn FeedIndexedAuth to ViewAuth to Edit
Public4-charYesYesNoneX-Wrify-Edit-Token or X-Wrify-Key
Unlisted4-charNoNoNone (URL is the secret)X-Wrify-Edit-Token or X-Wrify-Key
Secure unlisted8-charNoNoNone (URL practically unguessable)X-Wrify-Edit-Token or X-Wrify-Key
Password-protected4 or 8-charNoNoX-Wrify-Password, ?key=, or X-Wrify-Edit-TokenX-Wrify-Edit-Token or X-Wrify-Key
Open-edit4-charYesYesNoneNone (anyone can edit)

Write auth ≠ read auth. X-Wrify-Edit-Token grants both read and write access. X-Wrify-Password and ?key= grant read-only access. Responsible disclosure: security@wr.fi

Security Escalation Path

Start anonymous, escalate as needed. Each level adds protection without losing existing content.

  1. Anonymous push — no account needed. 30-day expiry, unlisted, 4-char URL. Good for quick sharing.
  2. Claim to account — sign in, claim the creation. Becomes permanent, attributed to you. Same URL.
  3. Secure URL{ "secure": true } or use wr.fi/u8. 8-char URL, practically unguessable.
  4. Password-protected — use wr.fi/up or set password in metadata. Recipients need X-Wrify-Password, ?key=viewKey, or X-Wrify-Edit-Token.

AI Provenance

Document how AI contributed to a creation using the provenance field.

Provenance Fields

FieldTypeDescription
toolstringThe AI tool used: "Claude Code", "Cursor", "ChatGPT", etc.
agentstringAgent or pipeline name
pipelinestringPipeline identifier
sourceRefsarrayArray of {type, uri, label} source references
parentCreationIdstringReference to a related creation (metadata-only, no automatic linking in UI). For versioning, use the update field instead.
aiContributionobjectAI contribution breakdown (see below)
sessionCountnumberNumber of AI sessions used
promptCountnumberTotal prompts sent

AI Contribution Object

FieldTypeDescription
percent*numberAI contribution percentage (0-100)
rolestringWhat AI did: "Full implementation", "Code generation", etc.
humanRolestringWhat humans did: "Architecture, review", "Direction", etc.

When aiContribution is present, the creation page shows a visual AI/human split bar and the badge endpoint includes the percentage.

Content-Type Metadata

Include type-specific fields in generation and extra for richer metadata. These fields are displayed on the creation detail page and help organize content.

Image

Generation: negativePrompt, steps, cfgScale, sampler, seed, width, height

Image example
{
  "generation": { "model": "stable-diffusion-xl", "steps": 30, "cfgScale": 7.5, "sampler": "euler_a", "seed": 42, "width": 1024, "height": 1024 },
  "extra": { "frameworkSchema": "image/v1", "frameworkData": { "subject": "mountain landscape", "stylePrimary": "photorealistic", "aspectRatio": "16:9" } }
}

Code

Generation: temperature, maxTokens

Code example
{
  "generation": { "model": "claude-opus-4-6", "temperature": 0.7 },
  "extra": { "frameworkSchema": "code/v1", "frameworkData": { "language": "python", "framework": "FastAPI", "purpose": "api" } }
}

Audio

Generation: voice, speed

Audio example
{
  "generation": { "model": "elevenlabs-v2", "voice": "rachel", "speed": 1.0 },
  "extra": { "frameworkSchema": "audio/v1", "frameworkData": { "type": "speech", "durationSeconds": 30, "sampleRate": 44100 } }
}

Video

Generation: seed

Video example
{
  "generation": { "model": "sora", "seed": 42 },
  "extra": { "frameworkSchema": "video/v1", "frameworkData": { "durationSeconds": 10, "resolution": "1920x1080", "fps": 24, "aspectRatio": "16:9", "style": "cinematic" } }
}

Text

Generation: temperature, maxTokens

Text example
{
  "generation": { "model": "gpt-4o", "temperature": 0.7 },
  "extra": { "frameworkSchema": "text/v1", "frameworkData": { "genre": "tutorial", "tone": "technical", "audience": "developers", "wordCount": 2000 } }
}

Framework Schemas

Attach structured metadata to creations using framework schemas. Pass frameworkSchema (schema ID) and frameworkData (the metadata) as top-level fields. Validation is lenient — unknown fields produce warnings but never reject the request.

View all 6 framework schemas

code/v1Code

Source code, scripts, and software projects.

FieldTypeDescription
language*stringPrimary programming language
frameworkstringFramework or runtime (e.g. Next.js, Express)
librariesstring[]Key libraries and dependencies
architectureDecisionsstring[]Notable architecture choices
estimatedComplexitystringComplexity: trivial, simple, moderate, complex, very-complex
purposestringWhat the code does
solvesstringProblem this code solves

image/v1Image

AI-generated or AI-edited images.

FieldTypeDescription
stylePrimarystringPrimary art style (e.g. photorealistic, anime)
styleTagsstring[]Additional style descriptors
aspectRatiostringAspect ratio (e.g. 16:9, 1:1)
colorMoodstringColor palette or mood
subjectstringMain subject of the image
resolutionobjectResolution as {width, height}
stepsnumberNumber of diffusion steps
cfgScalenumberCFG / guidance scale
seednumberRandom seed for reproducibility

text/v1Text

Written content — articles, stories, documentation.

FieldTypeDescription
genrestringGenre or category (e.g. tutorial, fiction, report)
tonestringWriting tone (e.g. formal, casual, technical)
audiencestringTarget audience
wordCountnumberApproximate word count
structurestringDocument structure (e.g. essay, listicle, Q&A)

audio/v1Audio

AI-generated audio — speech, music, sound effects.

FieldTypeDescription
typestringAudio type: speech, music, sfx, podcast
durationSecondsnumberDuration in seconds
sampleRatenumberSample rate in Hz
voiceModelstringVoice model or instrument used

video/v1Video

AI-generated video content.

FieldTypeDescription
durationSecondsnumberDuration in seconds
resolutionstringResolution (e.g. 1920x1080)
fpsnumberFrames per second
aspectRatiostringAspect ratio (e.g. 16:9)
stylestringVisual style or preset

workflow/v1Workflow

Multi-step AI pipelines and automation chains.

FieldTypeDescription
stepsobject[]Ordered list of pipeline steps
toolsUsedstring[]Tools and services in the pipeline
inputFormatstringInput data format
outputFormatstringOutput data format
Example: Push with framework schema
curl -X POST https://wr.fi/api/creations \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "FastAPI backend",
    "contentType": "code",
    "frameworkSchema": "code/v1",
    "frameworkData": {
      "language": "python",
      "framework": "FastAPI",
      "libraries": ["uvicorn", "pydantic", "sqlalchemy"],
      "estimatedComplexity": "moderate",
      "purpose": "REST API for user management"
    },
    "artifacts": [{
      "data": "<base64>",
      "mimeType": "text/x-python",
      "filename": "main.py"
    }]
  }'

Link a GitHub repository as an artifact instead of uploading files. The repo is displayed as a live card with stars, forks, and language info.

Push a repo-link
curl -X POST https://wr.fi/api/creations \
  -H "Content-Type: application/json" \
  -H "x-api-key: YOUR_API_KEY" \
  -d '{
    "title": "wr.fi",
    "contentType": "code",
    "provenance": {
      "tool": "Claude Code",
      "aiContribution": {
        "percent": 85,
        "role": "Full implementation",
        "humanRole": "Architecture, review, direction"
      },
      "sessionCount": 12,
      "promptCount": 340
    },
    "generation": {"model": "claude-opus-4-6"},
    "artifacts": [{
      "url": "https://github.com/owner/repo",
      "mimeType": "application/vnd.wrify.repo-link+json"
    }]
  }'

CLI

Full CLI for push, read, update, diff, and history. Auto-detects content type from file extension.

Commands
npx wrfi push <file> [options]       # Push a file
npx wrfi read <shortId>              # Read a creation
npx wrfi update <shortId> <file>     # Update (new version)
npx wrfi diff <shortId> [from]       # Show diff
npx wrfi history <shortId>           # Version history
npx wrfi mcp                         # Start MCP server

# Examples:
npx wrfi push hello.py                              # 4-char URL, 30-day expiry
npx wrfi push doc.md --secure                       # 8-char unguessable URL
npx wrfi push secret.md --password mypass            # password-protected
npx wrfi push file.ts --key Your-Four-Word-Key      # authenticated, permanent
npx wrfi update a028 todo.md --token Blue-Castle    # update with edit token

Options

FieldTypeDescription
--titlestringTitle (default: filename)
--typestringContent type (default: auto-detect)
--keystringAPI key (or WRFI_API_KEY env var)
--secureflag8-char unguessable URL
--passwordstringPassword-protect the creation
--tokenstringEdit token for updates
--messagestringVersion note for updates
--jsonflagOutput full JSON (for read/diff)

MCP Server

Native Model Context Protocol integration. One tool call instead of reading the page. Works with Claude Desktop, Cursor, and any MCP-compatible client.

Add to your MCP config
{
  "mcpServers": {
    "wrfi": {
      "command": "npx",
      "args": ["wrfi", "mcp"],
      "env": { "WRFI_API_KEY": "Your-Four-Word-Key" }
    }
  }
}

Available tools

FieldTypeDescription
wrfi_pushtoolCreate a new creation. Supports secure (8-char URL), unlisted, password-protected.
wrfi_push_securetoolCreate with 8-char unguessable URL (shorthand for push + secure:true).
wrfi_readtoolRead a creation by shortId. Supports password and edit token auth.
wrfi_updatetoolUpdate an existing creation (new version, same URL). Supports expectedVersion.
wrfi_difftoolGet unified diff between two versions.
wrfi_historytoolGet version history with titles, messages, and timestamps.

Sandboxed Environments

Some agent environments (Codex, CI/CD runners, restricted agents) cannot make outbound HTTP requests. Use the pre-fill URL approach — the agent generates the URL, the user clicks it.

How it works: The agent encodes the creation payload as base64, outputs a wr.fi/u?prefill=... URL, and the user clicks it to open the pre-populated upload form. No outbound requests needed from the agent.

Agent generates a pre-fill URL
# Agent builds the payload
payload = {
  "title": "Data Analysis Script",
  "contentType": "code",
  "textContent": "import pandas as pd\n...",
  "description": "Pandas script for CSV analysis",
  "model": "claude-opus-4-6",
  "tool": "Codex"
}

# Base64-encode and build URL
import base64, json
encoded = base64.b64encode(json.dumps(payload).encode()).decode()
url = f"https://wr.fi/u?prefill={encoded}"

# Output for user to click
print(f"Upload your creation: {url}")

URL length limit: Keep URLs under 8KB. For larger content, output a curl command or script instead:

Fallback for large content
curl -X POST https://wr.fi/api/p \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Large Dataset Analysis",
    "contentType": "code",
    "artifacts": [{
      "data": "'$(base64 < script.py)'",
      "mimeType": "text/x-python",
      "filename": "analysis.py"
    }]
  }'

AI-Readable Upload Page

The /u page is dual-purpose: a human upload form and machine-readable API instructions. Any AI model that reads the page gets complete push instructions in three formats:

<!-- HTML comment -->

Survives virtually all HTML parsing strategies. Contains full API instructions, endpoint URLs, all fields, and framework schemas.

<script type="text/wrify-instructions">

Same instructions in a script tag for tools that process DOM elements.

<script type="application/ld+json">

Schema.org WebAPI structured data for search engines and semantic parsers.

Pre-fill URLs

AI tools can pre-fill the upload form via query params or hash fragment. The user sees a review card with “Publish” and “Edit first” buttons.

Pre-fill with ?prefill= (recommended)
// JSON payload:
const data = {
  title: "My creation",
  contentType: "code",
  description: "A Python script",
  textContent: "print('hello')",
  model: "claude-opus-4-6",
  tool: "Claude Code"
};

// Generate URL:
const url = "https://wr.fi/u?prefill=" + btoa(JSON.stringify(data));
Pre-fill with individual query params
https://wr.fi/u?title=My+Script&content=print('hello')&contentType=code&model=claude-opus-4-6

Supported params: title, content, contentType, description, model, tool, tags
Legacy hash fragment method
https://wr.fi/u#BASE64_JSON=<base64-encoded JSON>

Embedding

Embed wr.fi creations in any website or blog post. Each creation has an embeddable card with live preview support.

Basic Embed

HTML embed code
<iframe
  src="https://wr.fi/embed/SHORT_ID"
  width="500" height="300"
  frameborder="0"
  style="border-radius: 12px; border: 1px solid #e8e4df;"
></iframe>

Live HTML Preview

For HTML and SVG creations, add ?mode=live to get an interactive preview with sandboxed execution:

Live embed
<iframe
  src="https://wr.fi/embed/SHORT_ID?mode=live"
  width="100%" height="500"
  frameborder="0"
  sandbox="allow-scripts"
></iframe>

Resources