Content API
Serve the posts Revnu writes on your own site and domain. The Content API returns published posts as JSON, read with an rvc_ token from Visibility → Publishing Settings; covers tokens, rotation, rate limits, the rebuild hook and backing up your posts if you leave.
The Content API serves the posts Revnu writes and publishes as JSON, so your own site renders them with its own design, on its own domain and framework. Revnu writes, fact-checks and publishes through the customer's approval settings. Your site fetches the result. Nothing about your stack changes.
This is a separate surface from the personal-token API: a different token, a different base URL, and read-only by construction.
The contract
Base URL: https://revnu.com/api/content/v1
Auth: Authorization: Bearer rvc_... (server-side env var only)
GET /posts all published posts, newest first, paged
GET /posts/{slug} one post, render-ready| Code | Meaning |
|---|---|
| 200 | ok |
| 400 | an unrecognised type, or a non-numeric since or limit on the list |
| 401 | missing or malformed Authorization header |
| 404 | unknown or revoked token, or unknown slug; indistinguishable on purpose |
| 429 | slow down; Retry-After is set |
Responses are never cached on Revnu's side. Your site's own build or revalidation is the cache.
Revnu counts your site as connected when it reads the first page of the full list: GET /posts with no type or since filter. A site that only ever sends filtered requests is never counted, so I've Connected It is refused and posts show as not on your site. Fetch the unfiltered list for your blog index.
Rate limit: about 300 requests a minute per token, with bursts of up to 600, so a full build that fetches the list and every post of a 200-post blog fits. Over the limit you get 429 with Retry-After; wait that many seconds and carry on. Page details: List posts and Get a post.
Getting a token
The token is created by the blog setup, not by hand. It's the "API key" the setup screen shows, and it starts with rvc_:
In the dashboard, open Visibility → Posts and enter the blog's address.
Choose whether to import existing posts or start with new posts only.
The Connect Your Site screen shows the
rvc_key once, with a setup prompt for you or your coding agent. Store the key in a server-side environment variable namedREVNU_CONTENT_API_KEY.
Lost the key? You can't view it again. Rotate it in Visibility → Publishing Settings → Content API (next section) and use the new one.
After setup, the Content API card lives in Visibility → Publishing Settings. It shows the endpoints, when the token was minted, and the rebuild hook.
Before you click I've Connected It
Deploy the integration with the current key.
Make sure your live site fetches the unfiltered post list on the server, for example by loading your blog index once.
Then click I've Connected It on the Connect Your Site screen.
Revnu opens your blog address once and waits a few seconds for your site to request posts. If it never does, the button is refused with "...hasn't requested any posts from Revnu yet". A request from your laptop with the key also counts, so test the deployed site, not a local copy. What the refusal means and how to clear it: Why isn't my post live?
Rotating the token
In Visibility → Publishing Settings → Content API, click Rotate Token. The new token is shown once. The old one stops working immediately, so update your environment variable and redeploy straight away. Revisiting the setup screen never rotates the key.
rvc_ and rvp_ tokens
rvc_ content token |
rvp_ personal token |
|
|---|---|---|
| Created in | The blog setup; rotated in Publishing Settings | Settings → Developers |
| Base URL | https://revnu.com/api/content/v1 |
https://revnu.com/api/v1 |
| Can do | Read posts already published on the blog | Act as you across Review, the agent, results, leads and workflows, within its scopes |
| If it leaks | Exposes only posts that are already public | Rotate it at once |
Never use an rvp_ token to fetch posts, and never ship either token to the browser.
The one hard rule
Render server-side or at build time. Next.js (SSG, ISR or SSR), Astro, Nuxt and SvelteKit all work. Fetching in the browser from a single-page app does not work for SEO: search and answer engines will not reliably see content that only exists after client-side JavaScript runs. For sites that can't render on the server, use the Revnu-hosted blog. Worked examples: Render posts in Next.js or Astro.
Rebuild hook for static sites
A site that fetches posts only at build time shows a new post only after a rebuild. Create a deploy hook on your host and paste its URL under Visibility → Publishing Settings → Content API → Rebuild Hook. Revnu POSTs to it whenever a post is published, updated or removed:
{ "event": "post.published", "blogSlug": "acme", "postSlug": "graph-rag", "updatedAt": 1753100000000 }event is post.published, post.updated or post.deleted. The ping is unsigned by design and carries nothing worth trusting: treat it only as "rebuild now", then read the posts through the authenticated API. Revnu doesn't retry a failed ping. A site using ISR or SSR doesn't need the hook.
A rebuild also removes posts. A post you delete in Revnu drops out of the list, so a build that reads the list leaves out its page and its sitemap entry.
No deploy hook on your host?
Some hosts (S3 and CloudFront, a self-built pipeline) have no deploy hook URL. Give Revnu a small endpoint of your own that starts your build instead. This one starts a GitHub Actions workflow through workflow_dispatch:
// A serverless function. Paste its URL, with ?key=..., as the Rebuild Hook.
export async function POST(req: Request) {
// The ping is unsigned, so gate it with a secret of your own.
if (new URL(req.url).searchParams.get("key") !== process.env.REBUILD_SECRET) {
return new Response("forbidden", { status: 403 });
}
await fetch("https://api.github.com/repos/OWNER/REPO/actions/workflows/deploy.yml/dispatches", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.GITHUB_TOKEN}`,
Accept: "application/vnd.github+json",
},
body: JSON.stringify({ ref: "main" }),
});
return new Response("ok");
}The workflow file needs on: workflow_dispatch, and the token needs permission to run Actions on that repo. Any other build trigger works the same way.
If you leave
The token isn't tied to your plan. Today it keeps returning your published posts after you cancel or a payment fails, and it stops working only if your account is deleted or the token is rotated. That's current behaviour, not a guarantee, so take a copy while you're a customer.
This saves every published post, as markdown and HTML, into a posts/ folder:
mkdir -p posts
cursor=""
while :; do
page=$(curl -s -H "Authorization: Bearer $REVNU_CONTENT_API_KEY" \
"https://revnu.com/api/content/v1/posts?limit=200${cursor:+&cursor=$cursor}")
for slug in $(echo "$page" | jq -r '.posts[].slug'); do
curl -s -H "Authorization: Bearer $REVNU_CONTENT_API_KEY" \
"https://revnu.com/api/content/v1/posts/$slug" > "posts/$slug.json"
sleep 0.2 # stays under the rate limit on large blogs
done
cursor=$(echo "$page" | jq -r '.cursor // empty | @uri')
[ -z "$cursor" ] && break
doneEach file holds the post's body.markdown, body.html, metadata, FAQ and hero image URL. Hero images are hosted by Revnu, so download any you want to keep. Without a developer, email support@revnu.com for an export before you cancel. Your posts keep their paths, so you can republish them at the same URLs on your next setup. Deleting your account: delete your account.
Canonical URLs and the hosted copy
Once the blog's destination is your site, every canonicalUrl, headMeta and jsonLd value points at your domain, and the copy on the Revnu-hosted blog is kept out of search results so it can't compete with your pages.
Search Console
Connect Google Search Console in the dashboard once your pages live on your domain. That is how Revnu sees, and reports, clicks, impressions and the queries you are winning. Without it the posts still ship, but reports can't include search performance. See Connect Google Search Console.
Frequently Asked Questions
Is this the same token as the personal API token?
No. Personal tokens start with rvp_, are minted in Settings → Developers and act as you across Review, the agent and results. Content tokens start with rvc_, come from the blog setup and can only read published posts.
Where do I find my Content API key?
It's shown once, on the Connect Your Site screen of the blog setup in Visibility → Posts. If you've lost it, rotate it in Visibility → Publishing Settings → Content API. The old key stops working immediately.
Which API key does my blog need?
The rvc_ Content API key from the blog setup. A personal rvp_ token from Settings → Developers is for the Revnu API, not your blog.
Why does I've Connected It say my site hasn't requested any posts?
Your live site hasn't fetched the unfiltered post list with the current key. Deploy with the current key, load your blog index once, then click again.
Can I go back to the Revnu-hosted blog later?
Yes. Email support@revnu.com and a person moves the blog's destination back to the hosted blog.
Does the API send webhooks?
It sends the rebuild-hook ping, a hint to rebuild when posts change. The ping carries no content and isn't signed, so read the posts themselves through the API.
Can my site save a copy of every post?
Yes. Page through GET /posts until cursor is null, then fetch each post. Each one includes both the markdown and the rendered HTML. If you leave has a script.
Does my Content API key still work after I cancel?
Yes, as Revnu works today: the key doesn't check your plan, so your site keeps fetching published posts. It stops if your account is deleted or you rotate the key. Back up your posts before you leave.
Where are the rate limits?
About 300 requests a minute per key, with bursts of up to 600. A 429 carries Retry-After.