The Content API is for sites that aren't on a supported CMS — a custom app (Next.js, Astro, Nuxt, SvelteKit…), a PHP site, or anything you build yourself. You pull your published articles as JSON and render them on your own domain (for example at yoursite.com/blog), in your own design.

Because the pages live on your domain, this is the best option for SEO — the content's link equity stays on your root domain, with no proxy and no DNS gymnastics. It's also the ideal fit for agencies: build the integration once, reuse it across every client site.

What you'll need

  • Your API key — open the Publishing tab of your site in app.pilotscribe.com, or just ask the assistant "give me my API key". It looks like pk_<site-id>.<signature>. Keep it in an environment variable (PILOTSCRIBE_API_KEY).
  • The base URLhttps://blog.pilotscribe.com/v1

Authentication

Send the key as a Bearer token (recommended) or as a ?key= query param. The API is read-only and returns only published articles. CORS is open, so both server-side and browser fetch work — but render server-side when you can, for SEO.

curl -H "Authorization: Bearer pk_<your-key>" \
  https://blog.pilotscribe.com/v1/articles

Endpoints

List articles

GET /v1/articles
{
  "site": { "name": "Acme", "lang": "en" },
  "total": 12,
  "articles": [
    {
      "slug": "ai-writing-tools",
      "title": "…",
      "metaDescription": "…",
      "excerpt": "…",
      "lang": "en",
      "publishedAt": "2026-06-04T12:00:03.378Z",
      "updatedAt": "2026-06-04T12:00:03.378Z",
      "imageUrl": "https://blog.pilotscribe.com/_media/articles/<id>.webp",
      "imageAlt": "…"
    }
  ]
}

One article by slughtml is rendered and sanitized (ready to inject); markdown is the raw body if you'd rather style it yourself.

GET /v1/articles/{slug}
{
  "slug": "ai-writing-tools",
  "title": "…",
  "metaDescription": "…",
  "lang": "en",
  "html": "<p>…</p>",        // rendered + sanitized — ready to inject
  "markdown": "…",            // raw, if you'd rather render it yourself
  "imageUrl": "…",
  "imageAlt": "…",
  "publishedAt": "…",
  "updatedAt": "…",
  "related": [ { "slug": "…", "title": "…" } ]
}

Example — Next.js (App Router)

// app/blog/page.tsx — your blog index, on YOUR domain
const { articles } = await fetch("https://blog.pilotscribe.com/v1/articles", {
  headers: { Authorization: `Bearer ${process.env.PILOTSCRIBE_API_KEY}` },
  next: { revalidate: 3600 },            // cache 1h, refresh in background
}).then((r) => r.json());
// → map articles to <a href={`/blog/${a.slug}`}>…</a>

// app/blog/[slug]/page.tsx — a single article
const a = await fetch(`https://blog.pilotscribe.com/v1/articles/${slug}`, {
  headers: { Authorization: `Bearer ${process.env.PILOTSCRIBE_API_KEY}` },
}).then((r) => r.json());
return (
  <article>
    {a.imageUrl && <img src={a.imageUrl} alt={a.imageAlt} />}
    <h1>{a.title}</h1>
    <div dangerouslySetInnerHTML={{ __html: a.html }} />
  </article>
);

Astro, Nuxt and SvelteKit are the same idea: fetch in your loader / getStaticPaths and render. Prefer build-time or ISR (e.g. revalidate hourly) so pages are static and fast.

Example — PHP

<?php
$key  = getenv('PILOTSCRIBE_API_KEY');
$ctx  = stream_context_create(['http' => [
  'header' => "Authorization: Bearer $key",
]]);
$json = file_get_contents(
  "https://blog.pilotscribe.com/v1/articles/" . urlencode($slug), false, $ctx);
$a = json_decode($json, true);

echo "<h1>" . htmlspecialchars($a['title']) . "</h1>";
echo $a['html']; // already sanitized

Good to know

  • Caching. Responses are cacheable for an hour; revalidate on a schedule rather than fetching on every request.
  • Images. imageUrl is an absolute URL served from our CDN — use it directly, or download and re-host if you prefer.
  • Sitemap. Add your /blog URLs to your own sitemap so search engines discover them on your domain.
  • Already on WordPress, Shopify, Webflow or Ghost? You don't need the API — use the direct CMS connector instead (no code).
  • Using an AI coding agent? Skip the manual setup — connect Claude, Cursor or Claude Code to our Integration MCP and it wires this API into your site for you. Any LLM can also read /llms.txt and /openapi.json.