Publish and update artifacts programmatically from Claude Code, scripts, or any HTTP client. All endpoints require an API key — create one at /settings.
Pass your API key in the Authorization header on every request:
Authorization: Bearer artfly_<your-key>
API keys are shown once on creation. If you lose a key, revoke it and create a new one.
https://www.artfly.net
All endpoints below are relative to this base URL.
/api/v1/artifacts/upload-url
Get a pre-signed upload URL for files larger than 4.5 MB
/api/v1/artifacts
Create a new artifact
/api/v1/artifacts/:publicId
Publish a new version of an existing artifact
/api/v1/artifacts
List your artifacts
Free accounts can publish artifacts up to 10 MB. Subscribers can publish up to 50 MB. Over the limit, the API responds 413 PAYLOAD_TOO_LARGE.
Sending html inline in the JSON body only works up to 4.5 MB (a platform limit on request bodies). For anything larger, upload the file first with the pre-signed URL flow below and pass object_key instead of html.
/api/v1/artifacts/upload-urlReturns a pre-signed URL that accepts a single PUT of your HTML, valid for 2 minutes. No request body. The response also tells you the size limit for your account.
Response
{
"upload_url": "https://<r2>/tmp/0b7c...html?X-Amz-...",
"object_key": "tmp/0b7c....html",
"expires_in": 120,
"max_bytes": 52428800
}Example — publish a large file
# 1. Get an upload URL
UPLOAD=$(curl -s -X POST https://www.artfly.net/api/v1/artifacts/upload-url -H "Authorization: Bearer $ARTFLY_API_KEY")
UPLOAD_URL=$(echo "$UPLOAD" | jq -r .upload_url)
OBJECT_KEY=$(echo "$UPLOAD" | jq -r .object_key)
# 2. PUT the HTML straight to storage (no API key needed — the URL is signed)
curl -s -X PUT "$UPLOAD_URL" -H "Content-Type: text/html; charset=utf-8" --data-binary @report.html
# 3. Create the artifact from the uploaded object
curl -s -X POST https://www.artfly.net/api/v1/artifacts -H "Authorization: Bearer $ARTFLY_API_KEY" -H "Content-Type: application/json" -d "{"object_key": "$OBJECT_KEY", "title": "Sales Report"}"/api/v1/artifactsRequest body (JSON)
| Field | Type | Description |
|---|---|---|
html | string | Full HTML content, inline. Up to 4.5 MB. Provide this or object_key. |
object_key | string | Key returned by /api/v1/artifacts/upload-url after you PUT the HTML there. Use for files over 4.5 MB (up to your account limit). |
title | string | Title. Extracted from <title> if omitted. |
expires_in | "never" | "7d" | "30d" | Expiration window. Default: "never". |
allow_indexing | boolean | Allow search engines to index. Default: false. |
comments_enabled | boolean | Enable comments. Default: false. |
Example
curl -X POST https://www.artfly.net/api/v1/artifacts \
-H "Authorization: Bearer artfly_<your-key>" \
-H "Content-Type: application/json" \
-d '{
"html": "<!DOCTYPE html><html><body><h1>Hello</h1></body></html>",
"title": "My artifact"
}'Response (201)
{
"artifact_id": "uuid",
"public_id": "aB3kX9mNpQ",
"url": "https://www.artfly.net/a/aB3kX9mNpQ",
"title": "My artifact",
"privacy": "public"
}/api/v1/artifacts/:publicIdPublishes a new version. The artifact URL stays the same — visitors always see the latest version.
Request body (JSON)
| Field | Type | Description |
|---|---|---|
html | string | New HTML content, inline. Up to 4.5 MB. Provide this or object_key. |
object_key | string | Key from /api/v1/artifacts/upload-url. Use for files over 4.5 MB. |
title | string | Override title. Extracted from HTML if omitted. |
Example
curl -X PUT https://www.artfly.net/api/v1/artifacts/aB3kX9mNpQ \
-H "Authorization: Bearer artfly_<your-key>" \
-H "Content-Type: application/json" \
-d '{
"html": "<!DOCTYPE html><html><body><h1>Updated!</h1></body></html>"
}'Response (200)
{
"public_id": "aB3kX9mNpQ",
"url": "https://www.artfly.net/a/aB3kX9mNpQ",
"version_number": 2,
"title": "Updated!"
}/api/v1/artifactsQuery parameters
| Param | Default | Description |
|---|---|---|
page | 1 | Page number (1-indexed). |
per_page | 20 | Results per page. Max 50. |
Example
curl "https://www.artfly.net/api/v1/artifacts?per_page=5" \ -H "Authorization: Bearer artfly_<your-key>"
Response (200)
{
"artifacts": [
{
"id": "uuid",
"public_id": "aB3kX9mNpQ",
"title": "My artifact",
"privacy": "public",
"status": "active",
"url": "https://www.artfly.net/a/aB3kX9mNpQ",
"updated_at": "2024-01-15T10:30:00Z",
"created_at": "2024-01-15T10:00:00Z"
}
],
"page": 1,
"per_page": 5,
"total": 42
}All errors return JSON with an error object:
{ "error": { "code": "UNAUTHENTICATED", "message": "Authentication required" } }| Code | Status | Meaning |
|---|---|---|
UNAUTHENTICATED | 401 | Missing or invalid API key |
VALIDATION_ERROR | 400 | Invalid request body or parameters |
PAYLOAD_TOO_LARGE | 413 | HTML exceeds your account's size limit (10 MB free, 50 MB subscribers) |
ARTIFACT_NOT_FOUND | 404 | No artifact with that public_id owned by you |
RATE_LIMITED | 429 | Too many requests — slow down |
Use the /artfly Claude Code skill to publish artifacts directly from your editor — no shell scripting needed. The skill handles JSON encoding, calls the API, and prints the URL.
Install the skill
.claude/commands/artfly.md inside any project where you want to use it..env.local: ARTFLY_API_KEY=artfly_<your-key>/artfly inside Claude Code — it will prompt for a file or let you paste HTML.Usage
# Publish a new artifact /artfly path/to/artifact.html # Publish a new version of an existing artifact /artfly update aB3kX9mNpQ path/to/artifact.html