easl docs

One API call turns raw agent output into a beautiful, shareable URL.

easl is a smart rendering layer for AI agents. Upload a CSV, Markdown file, JSON blob, or any supported content — easl detects the type and renders it with the best interactive viewer. No accounts required.

API Basehttps://api.easl.dev
Sites served athttps://{slug}.easl.dev
Anonymous limit50 files, 200 MB, expires in 7 days
Inline limit256 KB content, single file

Quick Start

The fastest way to publish: inline publish. One API call, content in the body, live URL in the response.

curl -X POST https://api.easl.dev/publish/inline \
  -H "Content-Type: application/json" \
  -d '{
    "content": "# Hello World\nSome **markdown** here.",
    "contentType": "text/markdown",
    "title": "My First Page"
  }'

# Response:
{
  "url": "https://warm-dawn.easl.dev",
  "slug": "warm-dawn",
  "expiresAt": "2026-03-30T..."
}

That's it. Your content is live and beautifully rendered.

Inline Publish (One-Call Magic)

The simplest publish method. Send content as a string, get a URL back instantly. No file uploads, no finalize step.

Supported content types

contentTypeRendered as
text/markdownStyled prose with headings, code, tables, blockquotes
text/csvSortable, filterable interactive table
application/jsonCollapsible tree viewer with syntax highlighting
text/htmlServed as-is
image/svg+xmlZoomable, sanitized SVG viewer
text/x-mermaidRendered Mermaid diagram (flowchart, sequence, etc.)
text/plainMonospaced text viewer

Examples

CSV → Interactive Table

curl -X POST https://api.easl.dev/publish/inline \
  -H "Content-Type: application/json" \
  -d '{
    "content": "Name,Role,City\nAlice,Engineer,SF\nBob,Designer,NYC",
    "contentType": "text/csv",
    "title": "Team Directory"
  }'

JSON → Tree Viewer

curl -X POST https://api.easl.dev/publish/inline \
  -H "Content-Type: application/json" \
  -d '{
    "content": "{\"users\": [{\"name\": \"Alice\", \"active\": true}]}",
    "contentType": "application/json",
    "title": "API Response"
  }'

Mermaid → Rendered Diagram

curl -X POST https://api.easl.dev/publish/inline \
  -H "Content-Type: application/json" \
  -d '{
    "content": "graph TD\n  A[Start] --> B{Decision}\n  B -->|Yes| C[Do it]\n  B -->|No| D[Skip]",
    "contentType": "text/x-mermaid",
    "title": "My Flowchart"
  }'

MCP Server

The MCP server lets AI agents publish content natively through the Model Context Protocol. Zero shell commands.

Installation

Add to your MCP configuration (Claude Desktop, Cursor, etc.):

{
  "mcpServers": {
    "easl": {
      "command": "npx",
      "args": ["-y", "@easl/mcp-server"]
    }
  }
}

Available tools

ToolDescription
publish_contentPublish raw content (string) → beautiful URL. The killer tool.
publish_filePublish a file from disk with presigned upload
publish_sitePublish a multi-file site (directory)
list_sitesList published sites in this session
delete_siteDelete a published site

Usage

Once configured, just ask your AI agent naturally:

// Your agent can now:
"Publish this CSV as a shareable table"
"Turn this markdown into a beautiful page"
"Show me this JSON in a tree view"
"Create a Mermaid diagram of the architecture"

REST API

Base URL: https://api.easl.dev

Publishing

POST /publish/inline

One-call publish. Send content as a string, get a live URL back instantly. No upload step needed.

Auth: None required (anonymous, 7-day TTL)

Request body

FieldTypeDescription
contentstring requiredRaw content string (max 256 KB)
contentTypestring requiredMIME type (e.g. text/markdown)
titlestring optionalPage title shown in header & browser tab
templatestring optionalTemplate: minimal, report, or dashboard

Response (201)

{
  "url": "https://warm-dawn.easl.dev",
  "slug": "warm-dawn",
  "claimToken": "claim_...",
  "embed": "<iframe src=\"...?embed=1\" ...></iframe>",
  "shareText": "My Page: https://warm-dawn.easl.dev",
  "expiresAt": "2026-03-30T12:00:00Z",
  "anonymous": true
}
POST /publish

Multi-file publish. Returns presigned R2 upload URLs for each file. Call /finalize after uploads complete.

Auth: None required

Request body

FieldTypeDescription
filesarray requiredArray of {path, size, contentType}
slugstring optionalCustom slug (3-48 chars, lowercase alphanumeric + hyphens)
titlestring optionalSite title
templatestring optionalTemplate name
ttlnumber optionalTTL in seconds (default: 7 days)

Response (201)

{
  "slug": "bold-arch",
  "url": "https://bold-arch.easl.dev",
  "claimToken": "claim_...",
  "upload": {
    "versionId": "v_abc123",
    "uploads": [
      {
        "path": "index.html",
        "method": "PUT",
        "url": "https://presigned-url...",
        "headers": { "Content-Type": "text/html" }
      }
    ],
    "finalizeUrl": "https://api.easl.dev/finalize/bold-arch",
    "expiresInSeconds": 600
  },
  "expiresAt": "2026-03-30T...",
  "anonymous": true
}

Finalize

POST /finalize/:slug

Activate a site after uploading all files via presigned URLs. Verifies all files exist in R2.

Auth: None required

Request body

FieldTypeDescription
versionIdstring requiredThe version ID from the publish response

Site Management

GET /sites/:slug

Get site metadata including title, files, version, and expiry.

Auth: None required

DELETE /sites/:slug

Delete a site. Requires the claim token from the original publish response.

Auth: X-Claim-Token header

cURL Examples

Publish markdown

curl -X POST https://api.easl.dev/publish/inline \
  -H "Content-Type: application/json" \
  -d '{"content":"# Report\n\nQ1 was great.","contentType":"text/markdown"}'

Publish CSV

curl -X POST https://api.easl.dev/publish/inline \
  -H "Content-Type: application/json" \
  -d '{"content":"Name,Score\nAlice,95\nBob,87","contentType":"text/csv"}'

Multi-file publish

# Step 1: Create site
curl -X POST https://api.easl.dev/publish \
  -H "Content-Type: application/json" \
  -d '{"files":[{"path":"index.html","size":1024,"contentType":"text/html"}]}'

# Step 2: Upload to presigned URL
curl -X PUT "PRESIGNED_URL" \
  -H "Content-Type: text/html" \
  --data-binary @index.html

# Step 3: Finalize
curl -X POST https://api.easl.dev/finalize/YOUR_SLUG \
  -H "Content-Type: application/json" \
  -d '{"versionId":"VERSION_ID"}'

Smart Rendering

easl's core feature. When a site is served, the Worker detects the file type and generates an HTML shell with the right interactive viewer. The raw data is embedded as JSON in a <script> tag, and client-side JavaScript hydrates it into a rich viewer.

Supported Types

File TypeDetectionViewer
CSV.csv or text/csvSortable table with column click-to-sort, alternating rows, sticky header
Markdown.md or text/markdownStyled prose — headings, lists, code blocks, blockquotes, tables, images
JSON.json or application/jsonCollapsible/expandable tree with syntax coloring and expand-all/collapse-all
HTML.html or text/htmlServed as-is (no wrapping, no viewer)
Images.png/.jpg/.gif/.webpResponsive centered image with max-width
SVG.svg or image/svg+xmlSanitized (scripts stripped), zoomable viewer
PDF.pdfEmbedded iframe viewer
Mermaid.mmd or text/x-mermaidRendered diagram via Mermaid.js CDN

Embed Mode

Add ?embed=1 to any site URL to get a clean, headerless version suitable for iframes:

<iframe
  src="https://warm-dawn.easl.dev?embed=1"
  width="100%"
  height="500"
  frameborder="0"
></iframe>

The embed URL is also returned in the embed field of the publish response.

Anonymous Sites

No account needed. Publish instantly and get a live URL.

LimitValue
Lifetime7 days
Max files per site50
Max total size200 MB
Inline content limit256 KB

Each publish returns a claimToken — save it if you need to delete the site later. Send it as the X-Claim-Token header on DELETE /sites/:slug.

Rate Limits

Publish endpoints are rate-limited per IP.

EndpointLimitWindow
/publish5 requests1 hour
/publish/inline10 requests1 hour

Error Codes

CodeMeaning
400Bad request — missing or invalid parameters
404Not found — site or version doesn't exist
409Conflict — slug taken or version mismatch
422Unprocessable — files missing from R2 during finalize
429Rate limited — try again later
500Server error