Documentation / REST API

Small API.
Useful output.

Publish a document, preserve a URL, or organize a collection. All endpoints are versioned under https://api.linkifact.com/v1.

Requests and identity

Guest publishing needs no bearer token. Account operations accept a scoped Linkifact API key. Browser sessions use secure host-only cookies on the app and API origins.

CONTENT TYPESapplication/json
multipart/form-data
MAX GUEST BODY1 MiB
API VERSIONv1

Artifact and collection routes

POST/v1/artifacts

Publish JSON or multipart HTML; auth optional

GET/v1/artifacts

List the current account's artifacts

GET/v1/artifacts/{id}

Read metadata as owner or guest manager

DELETE/v1/artifacts/{id}

Delete as owner or guest manager

POST/v1/artifacts/{id}/claim

Claim a guest artifact into the current account

POST/v1/artifacts/{id}/versions

Publish an authenticated version with If-Match

GET/v1/collections

List the current account's collections

POST/v1/collections

Create a collection

GET/v1/collections/{id}

Read an owned collection and its ordered items

PUT/v1/collections/{id}

Rename an owned collection

DELETE/v1/collections/{id}

Delete a collection, not its artifacts

POST/v1/collections/{id}/items

Add or reposition an owned artifact

DELETE/v1/collections/{id}/items/{artifactId}

Remove an item, not its artifact

GET/v1/api-keys

List API key metadata for the current browser session

POST/v1/api-keys

Create a scoped API key; the token is returned once

DELETE/v1/api-keys/{id}

Revoke an API key from the current browser session

POST/v1/abuse-reports

Report an artifact without loading it on the trusted origin

POST /v1/artifacts

Send JSON with html and optional title, or multipart with a file part and optional title. Use a unique idempotency key for safe retries.

POST /v1/artifacts HTTP/1.1
Host: api.linkifact.com
Content-Type: application/json
Idempotency-Key: 018f-demo

{
  "title": "Quarterly model",
  "html": "<!doctype html>..."
}

Guest response fields

id

Internal artifact identifier used by management endpoints.

url

Public, unlisted artifact URL. Anyone with this bearer link can view.

expires_at

Exact instant the public URL stops serving the artifact.

manage_url

Secret capability URL used to delete or claim. Returned once.

Keep the fragment secret

The management token lives after #, so browsers do not send it in the page request or referrer. The account app extracts it and passes it only to the API:

X-Linkifact-Manage-Token: <fragment-secret>

Use this header on artifact GET, DELETE, and claim requests. The raw token cannot be recovered by Linkifact after the initial response.

Optimistic, immutable versions

Authenticated artifacts retain a stable public URL. Send the current version in If-Match when publishing a new version. A stale value returns 409 Conflict; fetch fresh metadata before retrying.

Use the narrowest credential

Browser account routes use a secure session cookie. Agent clients send Authorization: Bearer lfk_…. Reading artifact metadata requires artifacts:read; publishing versions and deleting require artifacts:write; collection mutations require collections:write. API-key create, list, and revoke routes accept browser sessions only, so an API key cannot mint another key.

Create requests use { "name": "Codex on laptop", "scopes": ["artifacts:read", "artifacts:write"] }. Save the returned token immediately; only its hash is retained.

Assemble an unlisted collection

Create with { "name": "Release demos" }. Add or reposition an active owned artifact with { "artifact_id": "…", "position": 0 }; omit position to append. Collection responses include a public url on c.linkifactpages.com. That platform-rendered page is unlisted and noindex, but anyone with its URL can view it.

Report without rendering

Send artifact_id, a reason of malware, phishing, harassment, copyright, privacy, or other, plus optional bounded details and contact. Browser reports also send the configured Turnstile token. A successful submission returns 201 with an opaque report ID and open status.

Stable codes, useful request IDs

Non-2xx responses use one envelope. Branch on code, show message, and include request_id when reporting a problem.

{
  "error": {
    "code": "html_validation_failed",
    "message": "The HTML did not pass publication checks.",
    "request_id": "req_01J...",
    "details": {
      "issues": [{ "code": "external_url", "message": "..." }]
    }
  }
}

Documented error families cover authentication, validation, quota, expiry, conflict, plan limits, quarantine, and temporarily disabled guest publishing.

Retry deliberately

Retry 429 after the response's Retry-After delay. Retry transient 5xx failures with exponential backoff and the same idempotency key. Do not retry policy violations or size errors unchanged.