One post, with its rendered body
content.html is the body; content.toc lists its headings (each heading has the matching id). previous/next are the neighbouring published posts. Counting a view is a separate call — see POST /posts/{post}/views.
x-api-keyx-api-key<token>A tenant API key — secret (htk_…) or, where allowed, publishable (hpk_…).
post*stringThe post's slug (recommended) or id.
preview?booleanReturn the post whatever its status — for a draft preview page. Secret keys only; ignored with a publishable key.
include?array<string>design adds the raw block structure.
The post, its rendered body and its neighbours.
response?unknownapplication/jsoncurl -X GET 'https://api.horbit.ng/v1/public/blog/posts/five-lessons-open-data-hackathon'{ "status": true, "message": "Post retrieved successfully", "data": { "id": "3fb45a08bd18428cae49d3572c769237", "slug": "five-lessons-open-data-hackathon", "title": "Five lessons from our first open-data hackathon", "excerpt": "What 120 researchers taught us about sharing data in 48 hours.", "status": "published", "publishedAt": "2026-10-25T09:00:00.000Z", "updatedAt": "2026-10-25T10:12:44.000Z", "readingTimeMinutes": 4, "wordCount": 912, "isFeatured": true, "featuredImage": { "url": "https://cdn.horbit.ng/blog/hackathon.jpg", "alt": "Researchers around a table of laptops", "caption": "Day two, around 3am." }, "seo": { "title": "Open-data hackathon: five lessons", "description": "What 120 researchers taught us about sharing data in 48 hours.", "canonicalUrl": null, "ogImageUrl": "https://cdn.horbit.ng/blog/hackathon.jpg" }, "author": { "id": "7770812996284e9b92905104b95e36d2", "name": "Ada Obi", "avatarUrl": "https://cdn.horbit.ng/avatars/ada.jpg" }, "categories": [ { "id": "9c1d2e3f4a5b6c7d8e9f0a1b2c3d4e5f", "slug": "community-news", "title": "Community News", "color": "#3B9EFF", "parentId": null } ], "tags": [ { "id": "a1b2c3d4e5f60718293a4b5c6d7e8f90", "name": "Open Data", "slug": "open-data" }, { "id": "b2c3d4e5f60718293a4b5c6d7e8f90a1", "name": "Events", "slug": "events" } ], "stats": { "views": 1284, "comments": 12, "reactions": 87, "reactionCounts": { "like": 51, "love": 20, "clap": 12, "insightful": 4 } }, "commentsOpen": true, "reactionsOpen": true, "content": { "html": "<div class=\"hb-content\" data-hb-version=\"1\"><section class=\"hb-row hb-row--cols-1 hb-row--width-content\" data-row-id=\"sec-1\"><div class=\"hb-row__inner\"><div class=\"hb-col hb-col--span-12\"><div class=\"hb-block hb-text\" data-block-type=\"text\" data-block-id=\"blk-1\"><p class=\"hb-paragraph\">Open data changes who gets to ask questions.</p></div><h2 id=\"licences-matter\" class=\"hb-block hb-heading hb-heading--h2\" data-block-type=\"heading\" data-block-id=\"blk-2\">Licences matter</h2></div></div></section></div>", "toc": [ { "id": "licences-matter", "text": "Licences matter", "level": 2 } ] }, "previous": { "id": "1f2e3d4c5b6a79881726354453627180", "slug": "welcome-to-the-blog", "title": "Welcome to the blog", "publishedAt": "2026-10-01T09:00:00.000Z", "featuredImageUrl": null }, "next": null }}Published posts GET
Newest first by default. Filter by category, tag, author, featured flag and publish date; search title, excerpt and body; page with `page`/`limit` (max 100). Bodies are left out unless `include=content`.
Posts like this one GET
Published posts sharing the most tags and categories, then the newest.