Skip to content

Feed v1 reference

GET https://app.joogoos.com/feed/v1/sites/<site id>.json with the header Authorization: Bearer <JOOGOOS_FEED_KEY>. The key goes in the header only, never in the address.

Status When
200 JSON, Content-Type: application/json, with an ETag.
304 You sent If-None-Match with the last ETag and nothing changed.
401 Wrong, missing or replaced key, or no such site. Always an empty body.
429 More than 60 reads in an hour with this key.

Add ?sample=1 to get one made-up entry as well (frontmatter.sample: true), to build with before anything is published.

{
"version": 1,
"generatedAt": "2026-11-11T09:00:00.000Z",
"site": {
"id": "01a0fbb9-…",
"baseUrl": "https://example.com",
"blogPath": "/blog",
"trailingSlash": false,
"defaultLang": "en",
"languages": [{ "lang": "en", "prefix": "" }, { "lang": "fr", "prefix": "/fr" }]
},
"entries": [
{
"id": "…",
"articleId": "…",
"lang": "en",
"slug": "how-to-audit-carrier-invoices",
"path": "/blog/how-to-audit-carrier-invoices",
"url": "https://example.com/blog/how-to-audit-carrier-invoices",
"title": "How to audit carrier invoices",
"description": "Up to 155 characters, for the meta description.",
"publishedAt": "2026-11-10T09:00:00.000Z",
"modifiedAt": "2026-11-10T09:00:00.000Z",
"alternates": [
{ "hreflang": "en", "url": "https://example.com/blog/how-to-audit-carrier-invoices" },
{ "hreflang": "x-default", "url": "https://example.com/blog/how-to-audit-carrier-invoices" }
],
"frontmatter": {
"title": "How to audit carrier invoices", "description": "…", "slug": "how-to-audit-carrier-invoices",
"lang": "en", "publishedAt": "…", "modifiedAt": "…", "translationKey": "…"
},
"body": "## First heading\n\nMarkdown, from H2 down…",
"faq": [{ "question": "…", "answer": "…" }],
"jsonLd": [{ "@context": "https://schema.org", "@type": "BlogPosting" }],
"image": {
"url": "https://app.joogoos.com/feed/v1/covers/01a0fc12-….png",
"width": 1200, "height": 630,
"alt": "How to audit carrier invoices — Example Ltd"
}
}
],
"redirects": [{ "from": "/blog/old-slug", "to": "/blog/how-to-audit-carrier-invoices" }],
"gone": [{ "path": "/blog/taken-down", "since": "2026-11-09T12:00:00.000Z" }]
}
Field Meaning
baseUrl The site’s address, no trailing slash.
blogPath Where articles hang off, like /blog.
trailingSlash Whether article addresses end in /.
defaultLang The language articles are written in; others are translations.
languages Each published language and its path prefix ("" for the default).
Field Meaning
id This edition (article + language).
articleId Shared by every language of the article. Same as frontmatter.translationKey.
lang, slug Two-letter language; lower-case slug, at most 60 characters.
path, url Where to serve it: prefix + blog path + / + slug.
title The H1. At most 60 characters.
description The meta description. At most 155 characters.
publishedAt, modifiedAt ISO dates.
alternates Every published language of this article, then x-default: hreflang links. A language not published is never listed.
frontmatter The same fields as YAML frontmatter, for a content loader that wants files. May carry more keys later.
body Markdown starting at H2: headings, paragraphs, lists, quotes, bold, italics, links. No H1, no citations, and the FAQ is not in it.
faq Questions and answers to render under the article.
jsonLd Render as-is into one <script type="application/ld+json">. Made by code, not by a model.
image Optional. The article’s cover picture, 1200×630 PNG: put it at the top of the page and in the share tags (below). Missing until the cover is drawn, a few seconds after approval, so render without it.
Field Meaning
url Absolute and public, no key needed, so LinkedIn, WhatsApp and the rest can fetch it. A new title gives a new address, so it is safe to cache for ever. Copy it into your build if you prefer to serve it yourself.
width, height 1200 and 630.
alt What it shows (the title, and the business’s name): use it for alt and og:image:alt.

So a shared link shows the picture, put these in the article’s <head> when image is there:

<meta property="og:image" content="{image.url}">
<meta property="og:image:width" content="1200">
<meta property="og:image:height" content="630">
<meta property="og:image:alt" content="{image.alt}">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:image" content="{image.url}">
  • redirects: a slug changed after publishing. Answer 301 from from to to.
  • gone: withdrawn. Answer 410 (or 404).

Fields may be added to v1. Nothing is removed or changed in meaning. A breaking change would be served at /feed/v2/, beside v1, until sites move.