DEVELOPER DOCUMENTATION · API V1

Publish Liva articles
on your own platform.

Pull approved articles with the API, or receive signed webhooks when new articles are approved. Your integration publishes the content. Liva verifies the public result.

Start in Settings → Publishing → For developers. Only website owners and admins can manage integrations. API keys apply to one website and allow reading approved articles, claiming them for publication, and confirming their public URL. Keys are server credentials: never put them in frontend code.

1. Create an API key

The key is displayed once. Store it in your server's secret manager as LIVA_API_KEY. Rotation immediately invalidates the previous key. A removed administrator's key stops working. Maximum 60 API requests per website per minute; 429 includes Retry-After: 60.

export LIVA_API_BASE='https://gpsuqfjhkrvjqzoelfzl.supabase.co/functions/v1/nela-developer/v1'
# Set LIVA_API_KEY securely in your server environment.

2. Fetch approved articles

curl "$LIVA_API_BASE/articles?offset=0" \
  -H "Authorization: Bearer $LIVA_API_KEY"

Returns up to 20 articles and next_offset. Each article includes id, revision, title, slug, html, excerpt, sources, network_links and optional image. Only approved articles belonging to the key's website are returned. Incomplete articles carry article_not_ready instead of content.

Image URLs expire after one hour. Download and store the image on your own platform, keeping its alt text. Do not use the temporary URL as a permanent article image. The HTML includes citations and any assigned network links; preserve these links.

3. Claim before publishing

curl -X POST "$LIVA_API_BASE/articles/ARTICLE_ID/claim" \
  -H "Authorization: Bearer $LIVA_API_KEY" \
  -H "Content-Type: application/json" \
  --data '{"revision":7}'

This returns a stable export_id and a frozen article. Use this returned version, not an earlier preview. Claiming locks the article against edits, generation and native CMS publication. Repeating the same claim returns the same export; a changed revision is rejected.

Use export_id as your CMS's idempotency key. Save the external post ID durably before retrying any operation. If a creation response is lost, reconcile the existing post rather than creating another. Claims do not expire automatically: they remain locked while your integration resolves the publication.

curl "$LIVA_API_BASE/exports/EXPORT_ID" \
  -H "Authorization: Bearer $LIVA_API_KEY"

Fetch the saved export to resume an interrupted operation or refresh its image download URL. An export with status: "published" must not create a new post.

4. Confirm the public URL

curl -X POST "$LIVA_API_BASE/exports/EXPORT_ID/complete" \
  -H "Authorization: Bearer $LIVA_API_KEY" \
  -H "Content-Type: application/json" \
  --data '{"public_url":"https://your-domain.com/blog/article-slug"}'

The URL must be HTTPS on the website registered in Liva. It must serve the article as readable HTML without a login, redirect or browser-only rendering. Include the title, complete approved body, sources and network links. When the article has an image, render it in the page too. Liva checks the page before marking the article published. Failed verification leaves the export claimed; fix the page and retry the same URL. Successful repeated confirmations are idempotent.

Webhooks: receive approval events

Save a public HTTPS endpoint in publishing settings. Saving enables future approval events and replaces the signing secret. Existing approved articles are available through the API. No old approvals are sent automatically. Query parameters, private hosts and redirects are not supported.

Store the one-time whsec_… secret separately from your API key. Click Send test and inspect Delivery history. A test has type endpoint.test and never contains an article to publish.

{
  "id": "stable-event-uuid",
  "type": "article.ready",
  "created_at": "2026-09-25T12:00:00Z",
  "website_id": "your-website-uuid",
  "data": { "id": "article-uuid", "revision": 7, "title": "…", "html": "…" }
}

An approval event is a notification, not permission to skip the claim step. Call /articles/:id/claim with the event revision before publishing. An article may have changed or been withdrawn since the event was queued. A 409 means you must reconcile or fetch the current state.

Verify the signature

Headers: X-Liva-Event-Id, X-Liva-Timestamp (Unix seconds), X-Liva-Signature. The signature is v1= followed by the hex HMAC-SHA256 of eventId.timestamp.rawBody, using the literal signing secret. Reject timestamps more than five minutes from your clock and compare signatures in constant time.

Download Node.js signature verification helper

Delivery guarantees

Delivery is at least once. Persist verified events by event ID before returning a 2xx response, then publish in a background worker. Deduplicate both the event and the export. Respond within 10 seconds. A 2xx confirms receipt only; Liva still needs the separate public-URL callback.

The worker checks approximately every minute and retries failures up to eight total attempts, with exponential delays starting at one minute. The event ID stays stable; the timestamp, signature and temporary image URL may change on retry. Failed events can be retried from the app. Disabling or replacing the endpoint cancels queued events; a request already sent cannot be recalled.

Responses

StatusMeaning
200Request accepted; inspect the returned publication status.
400Invalid ID, revision, offset or public URL.
401 / 403Invalid/revoked key or insufficient access.
409Version conflict, article busy, or public page not yet verified.
429Rate limit reached. Wait before retrying.

API keys and signing secrets are never included in webhook payloads or delivery history. Customer content stays scoped to the selected website. The API exposes links already included in that article; it does not provide a directory of other network participants.