Public content API
Two read-only HTTPS endpoints return the articles a brand has published to its site with Refine. They are what @getrefine/next calls; use them directly to render articles on any stack (Astro, Nuxt, Rails, a static build).
Not the MCP server
This API only reads published articles and takes a public site key. Analytics, prompts and content generation are reached through the MCP tools with a secretrfn_live_ key.The site key#
Find it in Settings → Site publishing. There is one per brand; it looks like pk_ followed by 32 hexadecimal characters and is passed as the key query parameter.
It is public by design: it can only read what the brand already published on its own site, so it is safe in server code, build scripts and environment files. An article becomes readable here once publish_to_site (or the Publish button in Refine) has put it on the site; drafts and articles sent only to WordPress or Webflow are not listed.
List articles#
curl "https://app.refine-app.com/api/public/articles?key=pk_your_site_key"{
"articles": [
{
"slug": "best-crm-for-small-agencies",
"title": "Best CRM for small agencies in 2026",
"description": "How to pick a CRM when you run fewer than 20 people…",
"publishedAt": "2026-10-02T09:14:00.000Z",
"updatedAt": null
}
]
}Newest first, up to 500 articles, without bodies. An unknown or malformed key returns { "articles": [] } with a 200 rather than an error, so the endpoint never confirms which keys exist. An empty list from a key you expect to work means the key is wrong or nothing is published yet.
Get one article#
curl "https://app.refine-app.com/api/public/articles/best-crm-for-small-agencies?key=pk_your_site_key"{
"article": {
"slug": "best-crm-for-small-agencies",
"title": "Best CRM for small agencies in 2026",
"description": "How to pick a CRM when you run fewer than 20 people…",
"html": "<p>…</p><h2>…</h2>…",
"publishedAt": "2026-10-02T09:14:00.000Z",
"updatedAt": null
}
}Returns 404 with { "error": "Not found" } for an unknown slug or an unknown key.
Article fields
| Field | Type | Notes |
|---|---|---|
| slug | string | URL segment, stable once published. |
| title | string | "Untitled" when the article has none. |
| description | string | null | The meta description. |
| html | string | Single-article endpoint only. Sanitized HTML body; a leading H1 that repeats the title is removed, so render title yourself. |
| publishedAt | ISO 8601 | First publication on the site. |
| updatedAt | ISO 8601 | null | Currently always null. |
Caching and CORS#
Every response carries:
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, OPTIONS
Cache-Control: public, s-maxage=60, stale-while-revalidate=300A newly published article can take up to a minute to appear at the edge, plus your own cache (5 minutes by default with @getrefine/next). Browser calls work, but fetching from your server keeps the article in the HTML that AI crawlers read, which is the point of publishing it.