# Blog API > Read the articles, categories and tags of your Jazui blog to show them on your website. Source page: https://docs.jazui.com/api/blog/en You write on the blog from Jazui's dashboard and show it on your website with this API, with your own design. Each article includes its HTML, its Markdown version, the full `` for SEO (title, description, canonical, hreflang, Open Graph and structured data), the table of contents, translations and share links. Use the **PUBLIC Token**: it's read-only and safe in the browser. The API accepts requests from any domain (CORS), read-only. ## Endpoints | Path | Parameters | Returns | |---|---|---| | `GET /v2/blog/articles` | `site`, `lang`, `category`, `tag`, `q`, `page` (1), `pageSize` (10, max 50) | A page of summaries, newest first. | | `GET /v2/blog/articles/{slug}` | `site`, `lang`, `format` | A full article. | | `GET /v2/blog/articles/by-id/{id}` | `format` | An article by its ID. | | `GET /v2/blog/articles/{slug}/related` | `site`, `lang`, `count` (4, max 12) | Related articles. | | `GET /v2/blog/categories` | `site`, `lang` | Categories, including those with no articles yet. | | `GET /v2/blog/tags` | `site` | Tags that have articles. | | `GET /v2/blog/feed/{site}/rss` | `lang` | RSS 2.0, no token. | | `GET /v2/blog/feed/{site}/atom` | `lang` | Atom 1.0, no token. | `site` is the site's domain (`mysite.com`; `https://`, uppercase and paths are also accepted and stripped). If you manage several sites, always send it: that way each website only sees its own articles. Only **published** articles, or scheduled ones whose date has passed, are returned. ## Listing `category` also includes subcategories; `q` searches the title, summary, tags and content. ```bash curl -H "Authorization: Bearer $JAZUI_PUBLIC_TOKEN" \ "https://api.jazui.com/v2/blog/articles?site=misitio.com&lang=es&category=guias&page=1&pageSize=10" ``` ```json { "items": [ { "id": "7c1d0e2f-…", "slug": "como-funciona-el-prerender", "url": "https://misitio.com/blog/como-funciona-el-prerender", "site": "misitio.com", "language": "es", "title": "Cómo funciona el prerender", "summary": "Qué ven los bots de una SPA y cómo servirles el HTML completo.", "author": "Ana Pérez", "coverUrl": "https://api.jazui.com/Upload/Blog/…/portada.webp", "publishedDate": "2026-11-02T10:00:00Z", "updatedDate": "2026-11-03T08:15:00Z", "readingMinutes": 6, "categories": [{ "slug": "guias", "name": "Guías" }], "tags": [{ "slug": "seo", "name": "SEO" }] } ], "page": 1, "pageSize": 10, "totalItems": 24, "totalPages": 3 } ``` ## An article `format` decides which content comes back: `html` (default), `md` (Markdown only) or `both`. `markdownUrl` is always present: it's the article's public Markdown version, meant for AI. ```bash curl -H "Authorization: Bearer $JAZUI_PUBLIC_TOKEN" \ "https://api.jazui.com/v2/blog/articles/como-funciona-el-prerender?site=misitio.com&lang=es&format=both" ``` ```json { "id": "7c1d0e2f-…", "slug": "como-funciona-el-prerender", "url": "https://misitio.com/blog/como-funciona-el-prerender", "title": "Cómo funciona el prerender", "html": "

Qué ven los bots

…

", "markdown": "## Qué ven los bots\n\n…", "markdownUrl": "https://api.jazui.com/v2/sites/misitio.com/articles/es/como-funciona-el-prerender.md", "head": "Cómo funciona el prerender", "wordCount": 1240, "tableOfContents": [{ "level": 2, "id": "que-ven-los-bots", "text": "Qué ven los bots" }], "translations": [{ "language": "en", "slug": "how-prerendering-works", "url": "https://misitio.com/blog/how-prerendering-works" }], "metaTitle": "Cómo funciona el prerender | Mi sitio", "metaDescription": "Qué ven los bots de una SPA y cómo servirles el HTML completo.", "canonical": "https://misitio.com/blog/como-funciona-el-prerender", "socialImage": "https://api.jazui.com/Upload/Blog/…/portada.webp", "noIndex": false, "share": [{ "network": "linkedin", "name": "LinkedIn", "url": "https://www.linkedin.com/sharing/share-offsite/?url=…" }], "shareHtml": "
…
" } ``` - `head` has the tags for the `` of your article page: include them as they are so search engines, social networks and AI understand it. - `tableOfContents` holds the `h2` and `h3` headings with their `id`, for a linked table of contents. - `translations` has the same article in other languages. - If your plan carries the badge on articles, the HTML ends with «Published with Jazui». ## Categories and tags Categories come sorted by their order and name, with `parentSlug` for subcategories and `articleCount`. Tags only appear if they have articles. `GET /v2/blog/categories`: ```json [ { "slug": "guias", "name": "Guías", "description": "Paso a paso para sacar partido a tu web.", "icon": null, "language": "es", "site": "misitio.com", "order": 1, "parentSlug": null, "articleCount": 12 } ] ``` ## RSS and Atom The 20 most recent articles of a verified site, with the full content. No token needed. ```bash # Sin token: para lectores de RSS y agregadores curl https://api.jazui.com/v2/blog/feed/misitio.com/rss?lang=es curl https://api.jazui.com/v2/blog/feed/misitio.com/atom?lang=es ``` ## From the browser A minimal example with `fetch`. If your website is an SPA, remember bots see the blog thanks to your Jazui integration: `blog.js`: ```javascript const API = 'https://api.jazui.com/v2/blog'; const TOKEN = 'TU_PUBLIC_TOKEN'; // solo lectura: se puede usar en el navegador async function articulos(pagina = 1) { const url = `${API}/articles?site=misitio.com&lang=es&page=${pagina}&pageSize=9`; const response = await fetch(url, { headers: { Authorization: `Bearer ${TOKEN}` } }); if (!response.ok) throw new Error(`Blog: ${response.status}`); return response.json(); // { items, page, pageSize, totalItems, totalPages } } async function articulo(slug) { const url = `${API}/articles/${encodeURIComponent(slug)}?site=misitio.com&lang=es`; const response = await fetch(url, { headers: { Authorization: `Bearer ${TOKEN}` } }); if (response.status === 404) return null; const data = await response.json(); document.head.insertAdjacentHTML('beforeend', data.head); // título, metas y JSON-LD return data; } ``` ## Caching Every response has an `ETag`. Send it in `If-None-Match` and you'll get `304` with no body if nothing changed. Feeds can be cached for 15 minutes. ## Errors - `404 not_found`: the article doesn't exist or isn't published. - `400 ambiguous`: articles with that `slug` exist on several sites; add `?site=`.