Developer API
Every Fanvaiy publication has a free, open, read-only API. Pass your
siteId and pull
your published stories, categories and branding as JSON to power custom frontends, mobile apps, and content syndication. Render it however you like, in React,
Vue, Svelte, plain HTML, or anything that can fetch a URL. No API key, no SDK, no sign-up.
It serves public content, so there's nothing to authenticate. Call it from a browser or a server, with CORS enabled for any origin.
Only published, free stories and public site metadata are returned. Billing, drafts, paid articles and private fields are never exposed.
Every response carries Cache-Control and an ETag, so reads are served from cache and conditional requests return 304.
Open your Fanvaiy dashboard, where the site id sits in your site settings. You can also use your subdomain or custom domain in its place.
The base URL is:
https://fanvaiy.com/api/public/v1
Fetch your latest posts:
curl "https://fanvaiy.com/api/public/v1/sites/YOUR_SITE_ID/posts?limit=10"
A minimal example in JavaScript:
const SITE = 'YOUR_SITE_ID';
const res = await fetch(`https://fanvaiy.com/api/public/v1/sites/${SITE}/posts`);
const { data, meta } = await res.json();
data.forEach(post => {
console.log(post.title, '→', post.url);
});
All endpoints are GET, return JSON, and accept your site id, subdomain, or custom domain as {siteId}.
/api/public/v1/sites/{siteId}
Publication profile: name, branding (logo, favicon, colour, theme), social handles, contact, legal pages, SEO metadata, and the list of categories. The one call to bootstrap a frontend.
Example response
{
"data": {
"id": "d39dc768-…",
"name": "My Magazine",
"slogan": "Stories worth your time",
"color": "#111111",
"logo": "https://…/logo.png",
"theme": "news",
"lang": "en",
"url": "https://mymag.com",
"social": { "twitter": "mymag", "instagram": "mymag", "facebook": null },
"seo": { "ogTitle": "My Magazine", "ogImage": "https://…" },
"categories": [ { "id": "…", "name": "World", "slug": "world" } ]
}
}
/api/public/v1/sites/{siteId}/categories
Just the publication's categories, ordered the way they appear on the site.
Example response
{
"data": [
{ "id": "…", "name": "World", "slug": "world", "isPromoted": true },
{ "id": "…", "name": "Sports", "slug": "sports", "isPromoted": false }
]
}
/api/public/v1/sites/{siteId}/posts
Published stories, newest first (paid posts excluded). Returns story summaries without the article body.
Query parameters
category
string
Filter by category slug.
featured
boolean
Set to true to return only featured posts.
search
string
Full-text match on title and summary.
page
integer
Page number (default 1).
limit
integer
Per page, 1–50 (default 20).
Example response
{
"data": [
{
"id": "581aac37-…",
"title": "Crafting a Gripping Horror Story",
"summary": "Learn how to write a horror story that…",
"image": "https://…/cover.jpg",
"isFeatured": false,
"publishedAt": "2026-05-10T08:30:00+00:00",
"likes": 12,
"tags": ["writing", "horror"],
"url": "https://mymag.com/story/581aac37-…",
"category": { "name": "Writing", "slug": "writing" },
"author": { "name": "Aisha", "profilePicture": "https://…" }
}
],
"meta": { "page": 1, "limit": 20, "total": 134, "totalPages": 7 }
}
/api/public/v1/sites/{siteId}/posts/{id}
A single post including the full HTML body, author, category, and audio (if the article has a narration).
Example response
{
"data": {
"id": "581aac37-…",
"title": "Crafting a Gripping Horror Story",
"summary": "Learn how to write a horror story that…",
"body": "<p>The first rule of horror is…</p>",
"image": "https://…/cover.jpg",
"publishedAt": "2026-05-10T08:30:00+00:00",
"url": "https://mymag.com/story/581aac37-…",
"category": { "name": "Writing", "slug": "writing" },
"author": { "name": "Aisha", "profilePicture": "https://…" },
"audio": { "url": "https://…/narration.mp3", "duration": 412 }
}
}
Posts behind a paywall are never returned by this API, neither in lists nor by direct id. Only free, published posts are public.
Responses are cacheable and carry an ETag. Send it back as If-None-Match to get a fast 304 Not Modified when nothing changed.
There's a generous safety limit per IP. For high-traffic frontends, cache responses on your side, since the data changes infrequently.
Unknown or blocked sites and missing posts return 404 with a JSON body. All responses are JSON.
Launch a Fanvaiy publication in minutes, then build any frontend you like on top of it.
Start a publication