REST API
Base path: /api/v1
All clip endpoints accept and return JSON unless noted. PIN-protected clips require
the X-Clip-Pin header or a ?pin= query parameter.
Health check
/api/health
Returns service status.
{ "status": "ok", "version": "0.3.0" }
Read a clip
/api/v1/clips/:slug
Fetches clip content. Counts as a read for burn-on-read clips and view limits. Link-preview crawlers receive a preview response without consuming a read.
Response (200):
{
"slug": "my-clip",
"content": "hello",
"contentType": "text",
"expiresAt": 1720000000,
"burnOnRead": false,
"maxViews": null,
"viewCount": 1,
"webhookUrl": null
}
After a burn-on-read clip is consumed, the final response includes "burned": true.
Errors: 400 invalid slug, 401 PIN required, 404 not found, 429 rate limited.
Create a clip
/api/v1/clips/:slug
Creates a new clip. Returns 409 if the slug already exists.
JSON body (all fields optional):
{
"content": "secret note",
"burnOnRead": true,
"ttl": 3600,
"maxViews": 3,
"pin": "1234",
"webhook": "https://example.com/hook"
}
burnOnRead— defaults totrue. Setfalseor providettlfor a persistent clip.ttl— seconds until expiry (e.g.3600= 1 hour).maxViews— delete after N API reads (0= unlimited).pin— lock the clip; stored as a bcrypt hash.webhook— URL notified on read, burn, or expiry (see Webhooks).
Plain-text body is also accepted (Content-Type: text/plain) as the clip content.
Response (201):
{
"slug": "my-clip",
"content": "secret note",
"maxViews": 3,
"webhookUrl": "https://example.com/hook",
"pinSet": true
}
Update a clip
/api/v1/clips/:slug
Replaces clip content. Creates the clip if it does not exist.
curl -X PUT https://webklip.com/api/v1/clips/my-clip \
-H "Content-Type: application/json" \
-d '{"content":"updated text"}'
Delete a clip
/api/v1/clips/:slug
Permanently deletes the clip, attached files, and version history.
{ "ok": true }
Download a file
/api/v1/files/:slug/:fileId
Returns the raw file bytes. Requires PIN header/query when the clip is locked. File IDs are shown in the clip UI after upload.
Rate limits
API responses include X-RateLimit-Remaining. When the limit is exceeded the
server returns 429 with { "error": "Rate limit exceeded" }.