Mentionwell

The Mentionwell public API is small, RESTful, and read-only. Two endpoints cover almost every integration; three more give you syndication feeds.

Base URL

https://mentionwell.com

Self-hosted deployments use their own origin. Set this in MENTIONWELL_API_URL on your destination site.

Conventions

  • Auth: Authorization: Bearer <site-api-key> on the /api/public/* endpoints. Feeds and sitemaps are open.
  • Content type: application/json (or application/rss+xml / application/feed+json / application/xml for feeds and sitemap).
  • Timestamps: ISO-8601, UTC.
  • Caching: post endpoints return Cache-Control: public, max-age=60, s-maxage=300, stale-while-revalidate=600.
  • CORS: Access-Control-Allow-Origin: *, with OPTIONS preflight support.
  • Envelope: every JSON response is { "ok": boolean, ... }. On error, ok: false with a message field.

List posts

GET /api/public/{siteSlug}/posts

Returns up to limit published posts for one site, newest first. Use this for your /blog index page.

Path parameters

Name Type Description
siteSlug string (required) The slug of your site, as shown in the dashboard URL.

Query parameters

Name Type Description
limit integer (optional) Maximum posts to return. Default 20, max 100. Clamped server-side.

Example — cURL

curl https://mentionwell.com/api/public/your-site-slug/posts?limit=12 \
  -H "Authorization: Bearer bgo_read_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"

Example — JavaScript

const res = await fetch(
  `${process.env.MENTIONWELL_API_URL}/api/public/${siteSlug}/posts?limit=12`,
  {
    headers: { Authorization: `Bearer ${process.env.MENTIONWELL_API_KEY}` },
    next: { revalidate: 300, tags: ["mentionwell:posts"] }
  }
);
const { posts } = await res.json();

Example — Python

import os, httpx

r = httpx.get(
  f"{os.environ['MENTIONWELL_API_URL']}/api/public/{site_slug}/posts",
  params={"limit": 12},
  headers={"Authorization": f"Bearer {os.environ['MENTIONWELL_API_KEY']}"}
)
posts = r.json()["posts"]

Response

{
  "ok": true,
  "site": { "slug": "your-site-slug", "name": "Your Site", "domain": "yoursite.com" },
  "posts": [
    {
      "slug": "five-questions-to-ask-before-you-buy",
      "title": "Five Questions to Ask Before You Buy",
      "excerpt": "A short, scannable summary that drops into your card UI.",
      "metaDescription": "150-character SEO description.",
      "featuredImage": "https://cdn.mentionwell.com/.../hero.jpg",
      "readingTime": 7,
      "tags": ["buying", "first-home"],
      "category": { "title": "Buying", "slug": "buying" },
      "publishedAt": "2026-04-21T15:00:00.000Z",
      "updatedAt": "2026-04-21T15:00:00.000Z",
      "author": { "name": "Editorial Team", "avatarUrl": null, "url": null },
      "canonicalUrl": null
    }
  ]
}

The list endpoint omits heavy fields (html, markdown, tldr, toc, faqs, jsonLd) to keep payloads small. Fetch the detail endpoint for those.


Get post

GET /api/public/{siteSlug}/posts/{slug}

Returns the full post: HTML body, table of contents, FAQ, JSON-LD, author block. Use for /blog/[slug] detail pages.

Path parameters

Name Type Description
siteSlug string (required) The slug of your site.
slug string (required) The slug of a published post.

Example

curl https://mentionwell.com/api/public/your-site-slug/posts/five-questions-to-ask-before-you-buy \
  -H "Authorization: Bearer bgo_read_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"

Response

{
  "ok": true,
  "post": {
    "slug": "five-questions-to-ask-before-you-buy",
    "title": "Five Questions to Ask Before You Buy",
    "metaTitle": "Five Questions to Ask Before You Buy a Home | Your Site",
    "metaDescription": "Short SEO description.",
    "excerpt": "...",
    "html": "<header class=\"wb-header\">...</header><section class=\"wb-section\">...</section>",
    "markdown": "# Five Questions...\n\n...",
    "featuredImage": "https://cdn.mentionwell.com/.../hero.jpg",
    "readingTime": 7,
    "tags": ["buying", "first-home"],
    "category": { "title": "Buying", "slug": "buying" },
    "publishedAt": "2026-04-21T15:00:00.000Z",
    "updatedAt": "2026-04-21T15:00:00.000Z",
    "author": { "name": "Editorial Team", "avatarUrl": null, "url": null },
    "tldr": { "items": ["Takeaway 1", "Takeaway 2", "Takeaway 3"] },
    "toc": [{ "id": "intro", "title": "Introduction", "level": 2 }],
    "faqs": [{ "question": "Is now a good time to buy?", "answer": "..." }],
    "canonicalUrl": null,
    "jsonLd": "{\"@context\":\"https://schema.org\",\"@type\":\"Article\",...}"
  }
}

RSS feed

GET /api/sites/{siteSlug}/feed.xml

Standard RSS 2.0. Public, no authentication. Add it to your <head>:

<link rel="alternate" type="application/rss+xml"
      title="Your Site Blog"
      href="https://mentionwell.com/api/sites/your-site-slug/feed.xml" />

JSON Feed

GET /api/sites/{siteSlug}/feed.json

JSON Feed 1.1 format. Useful for n8n / Zapier / Make automations and AI ingestion pipelines.

Sitemap

GET /api/sites/{siteSlug}/sitemap.xml

Standard sitemap.xml. Submit to Google Search Console and Bing Webmaster Tools.


Errors

All errors return a JSON envelope:

{ "ok": false, "message": "Human-readable description." }
Status Meaning What to do
400 Malformed request Check the path and query parameters against this reference.
401 Unauthorized Missing or wrong Authorization header.
404 Site or post not found Verify the slug; treat as a normal no-result state in your UI.
5xx Origin error Retry with exponential backoff. Cached responses still serve via SWR.

Versioning

The public API is currently un-versioned because additive changes only. If a breaking change ever ships, it will land at a new path prefix and the existing one will continue to serve.