API and Webhooks

Publish your blog anywhere

overrank writes and publishes SEO articles on a schedule. Pull them from a read-only content API, or receive a signed webhook the moment each one goes live, and render them inside any site you build, including a custom React or headless stack.

Pull  you fetch our APIPush  we POST to your endpointHosted  we serve your subdomain

Overview

Every article carries a title, ready-to-render HTML, a hero image, meta description, slug, and FAQs. However you connect, articles publish automatically once the site is set up. You never write content by hand.

Which one to use

Pull

Content API

Fetch published articles as JSON and save them into your own database or render them at build time. Ideal for a custom or headless site built on any stack.

Push

Webhook

We POST each new article to an endpoint you own, signed so you can verify it. No polling on your side. The article lands in your database the moment it publishes.

Hosted

Subdomain

Prefer to wire up nothing? We serve the blog as real server-rendered pages at blog.yourdomain.com. You point one DNS record at us.

Content API / pull

A public, read-only endpoint keyed by the site domain. No API key, because it serves the same published articles anyone can read on the live blog. CORS is open, so you can call it from a browser, a build step, or a serverless function.

List every published article

GEThttps://www.overrank.ai/api/articles/public?site=clientdomain.com
200 application/json
{
  "articles": [
    {
      "id": "a1c3d0e2-...-e9",
      "title": "How to Winterize Your Sprinkler System",
      "slug": "how-to-winterize-your-sprinkler-system",
      "excerpt": "A step-by-step guide to protecting your lines.",
      "metaDescription": "Learn when and how to winterize...",
      "thumbnailUrl": "https://images.pexels.com/photos/1571...jpg",
      "publishedAt": "2026-07-26T15:03:00.000Z",
      "readingTime": 6
    }
  ],
  "site": { "name": "Ridgeline Plumbing", "domain": "clientdomain.com" }
}

Fetch one full article

Add &slug=. This returns the full HTML body plus FAQs and related posts.

GEThttps://www.overrank.ai/api/articles/public?site=clientdomain.com&slug=how-to-winterize-your-sprinkler-system
200 application/json
{
  "id": "a1c3d0e2-...-e9",
  "title": "How to Winterize Your Sprinkler System",
  "slug": "how-to-winterize-your-sprinkler-system",
  "metaDescription": "Learn when and how to winterize...",
  "content": "<p>When the first hard frost arrives...</p><h2>...",
  "excerpt": "A step-by-step guide to protecting your lines.",
  "thumbnailUrl": "https://images.pexels.com/photos/1571...jpg",
  "publishedAt": "2026-07-26T15:03:00.000Z",
  "wordCount": 1180,
  "readingTime": 6,
  "faqs": [
    { "question": "When should I winterize?", "answer": "Before the first hard freeze." }
  ],
  "siteName": "Ridgeline Plumbing",
  "relatedArticles": [
    { "title": "Signs of a Slab Leak", "slug": "signs-of-a-slab-leak" }
  ]
}

The single-article response also includes a ctaButton and a couple of display hints the embed uses. You can ignore those for a headless build.

Field reference

The fields on a full article. The webhook payload uses this same shape, so one parser covers both.

FieldTypeNotes
titlestringThe article headline. Render this as your own H1.
slugstringUnique and stable per site. Use it as your upsert key.
contentstring (HTML)Ready-to-render body. Contains no H1 by design.
metaDescriptionstringFor your meta description tag.
thumbnailUrlstring (URL)Absolute hero image URL. Hot-link or rehost.
excerptstringShort summary for cards and previews.
faqsarrayQuestion and answer pairs. Good for FAQ schema.
publishedAtISO 8601When the article went live.
wordCount, readingTimenumberLength and estimated minutes to read.

What to know

  • The title is separate from the body. content has no H1, so render <h1>{title}</h1> above it and you avoid duplicate headings.
  • Poll on a schedule, upsert by slug. New and updated articles come through cleanly, whether you fetch at build time or on a cron.
  • Images are absolute URLs. Download and rehost into your own storage, or hot-link them as-is.
  • Render server-side. SSR or SSG makes the posts fully crawlable by Google, Google AI Overviews, Gemini, and Bing, which is the real advantage of the headless route over a client widget.

Webhooks / push

Rather than poll, receive each article at an endpoint you own. Tell us the URL you want deliveries sent to and we turn it on and send you a signing secret. Every request is signed so you can trust it came from overrank.

POSThttps://your-app.example.com/hooks/overrank
Request headers
Content-Type: application/json
User-Agent: overrank-webhooks/1
X-Overrank-Event: article.published
X-Overrank-Timestamp: 2026-07-26T15:03:00.000Z
X-Overrank-Signature: sha256=6f3b0a9c4d2e...b71f

The request body is identical to the single-article response above, so the parser you write for the pull API handles webhook deliveries too.

Verifying a delivery

The signature is an HMAC-SHA256 of timestamp + "." + rawBody using your secret, hex-encoded and prefixed sha256=. Recompute it over the raw request body and compare in constant time. The timestamp is folded in so a captured payload cannot be replayed.

verify.js Node
import crypto from "crypto";

// rawBody is the exact bytes we sent, not a re-serialized object.
function verifyOverrank(rawBody, headers, secret) {
  const ts = headers["x-overrank-timestamp"];
  const expected = "sha256=" + crypto
    .createHmac("sha256", secret)
    .update(`${ts}.${rawBody}`)
    .digest("hex");
  const got = headers["x-overrank-signature"];
  return got.length === expected.length &&
    crypto.timingSafeEqual(Buffer.from(got), Buffer.from(expected));
}

Delivery and retries

  • Fires on publish. You get article.published the moment an article goes live, including the very first one.
  • Automatic retry. If your endpoint is down, we retry on the next cycle and never re-send an article you already accepted.
  • Respond with 2xx. Any 2xx marks the delivery accepted. We wait up to 10 seconds for a response.
  • Point it anywhere public over HTTPS. The target must be an https URL to a public host.

Hosted subdomain

If you would rather not wire up anything, we serve the blog as real server-rendered pages at blog.yourclient.com. You point one CNAME record at us and the posts are live and crawlable, with no code on your side. Reach out and we will set it up with you.

Notes

  • Published content only. Both surfaces expose the same articles that are already public on the live blog. No drafts, no account data.
  • You own your content. Everything overrank writes for you is yours to keep, export, and host.
  • Stable fields. These field names are the v1 contract. We will not rename or remove one without a heads-up.
  • Questions? Email hello@overrank.ai and we will help you wire it up.