Prismic scout: Slice Machine, the public CDN API, and the Type Builder switch
Prismic is a French-origin hosted headless CMS. Like Storyblok or Contentful, the source is closed and there is no self-host build. The signature feature is slices — content models that live in your repo as React/Vue/Svelte components and sync to the cloud through a CLI called Slice Machine. We did the next-best scouting test: we hit the public Content API at cdn.prismic.io/api/v2, captured the master-ref handshake, broke it on purpose, and read what the docs themselves admit about Slice Machine being quietly replaced. Screenshots taken on the date stamped above.
We're the team behind SimpleReview, a Chrome extension that drafts code-fix PRs on whatever site you click. We are not affiliated with Prismic, we're not a partner, we don't get paid to recommend anything. This page is a scout's notebook from one Linux box on one date. Prismic is SaaS-only, so we did not deploy a stack — we tested the parts you can test from outside: the public website, the public Content API, the developer docs, and the public issue trackers on the SDKs. If we got a number wrong, open an issue and we'll correct it.
What "SaaS-only" means here
Prismic runs on AWS, fronted by CloudFront. The repository (their word for an instance — every project gets <name>.cdn.prismic.io) is provisioned by them, the schema lives in their dashboard or in your repo via Slice Machine, and the source is closed. There is no community Docker image, no Helm chart, no on-premise SKU. Self-hosting Prismic is not a question of "find the right config" — it isn't an option. If that's a hard constraint (data sovereignty, air-gapped networks, no third-party DPAs), stop here and look at Strapi or Directus.
Friction 1 — pricing leads with Free, but the second tier is a $150 cliff
prismic.io/pricing — 2026-05-07. Annual toggle on; the gap between Free and Medium is wider than most competitors'.The plan names on the test date: Free ($0), Medium ($150/mo, annual), Platinum ($675/mo, annual), Enterprise (custom). We're not restating the limit grid here for SEO — we're restating the prices because the shape of this ladder is unusual. Free is generous on the surface ("for developers building personal websites or a PoC"), but the moment a project graduates beyond a single repository, you don't pay $20 — you pay $150. Storyblok's first paid tier is $99/mo, Contentful's Lite is $300/mo. Prismic's Medium sits between them and tries to do both.
What you're paying for at Medium, per the comparison grid: more API calls, more locales, more user seats, scheduled publishing, and the Asset CDN. The number that matters most to a small team is the seat count — Free is one repository with limited collaborators; Medium is the first plan where multiple editors are practical. If your project will have one developer and zero non-technical editors, Free might genuinely carry you. If anyone else will publish, you're on the $150 plan whether you wanted to be or not.
First-hand artifact — the public Content Delivery API
Every Prismic repository exposes https://<repo>.cdn.prismic.io/api/v2. The shape is two-step: hit /api/v2 first to discover the master ref (Prismic's content version stamp), then hit /api/v2/documents/search?ref=<ref> with that ref to get documents. Here's what we got at 07:06 UTC on 2026-05-08 from a Hetzner box, against a real test repository (example-prismic) used by several Prismic SDK demos:
$ curl -sSL -D - "https://example-prismic.cdn.prismic.io/api/v2"
HTTP/2 200
content-type: application/json; charset=utf-8
content-length: 2286
server: CloudFront
x-prismic-region: eu-west-2
x-prismic-version: 6
cache-control: max-age=0, no-store
access-control-allow-origin: *
x-cache: Miss from cloudfront
x-amz-cf-pop: HEL51-P4
{
"refs": [{"id":"master","ref":"W3ROxyYAAPeuMvvg","label":"Master","isMasterRef":true}],
"types": {"blog":"Blog","page":"Page"},
"languages": [{"id":"es-es","name":"Spanish - Spain (Traditional)"}],
"forms": {
"everything": {
"method": "GET",
"action": "https://example-prismic.cdn.prismic.io/api/v2/documents/search",
"fields": {"ref":..., "q":..., "lang":..., "page":..., "pageSize":..., "graphQuery":..., ...}
}
},
"oauth_initiate": "https://example-prismic.prismic.io/auth",
"oauth_token": "https://example-prismic.prismic.io/auth/token",
"version": "482083b"
}
Three observations from the wire:
- The repository is in
eu-west-2(London) perx-prismic-region, served by CloudFront edgeHEL51-P4(Helsinki). Prismic doesn't advertise multi-region routing the way Storyblok does — your data sits where the repository was provisioned, and the CDN gets it close to readers from there. - The response is a discovery document, not the content. You get back the master ref (
W3ROxyYAAPeuMvvg), the list of content types, the available languages, and a description of the search forms. Every Prismic SDK starts by parsing this. The whole content tree is one extra request away. cache-control: no-storeon the discovery endpoint,max-age=315360000on the search endpoint (we'll see that one below). Prismic invalidates the master ref on every publish, so you re-fetch/apioften but cache document responses near-permanently — keyed by ref. Smart, but it means a stale ref gives you stale content forever until you re-discover.
Asking for documents with that ref returns a real, well-formed payload — three pages, two stories per page:
$ curl -sSL "https://example-prismic.cdn.prismic.io/api/v2/documents/search?ref=W3ROxyYAAPeuMvvg&pageSize=2"
{
"page": 1, "results_per_page": 2, "results_size": 2,
"total_results_size": 3, "total_pages": 2,
"next_page": "https://example-prismic.cdn.prismic.io/api/v2/documents/search?ref=W3ROxyYAAPeuMvvg&page=2&pageSize=2",
"results": [
{"id":"W3ROryYAADHBMvt1","uid":"test2","type":"page","first_publication_date":"2018-08-15T16:03:19+0000",
"lang":"es-es","data":{"groupfields":[{"image1":{"dimensions":{"width":960,"height":800}, ...}}]}},
{"id":"W3RNpyYAADHBMvbc","uid":"otro-uid","type":"page", ...
"data":{"title":[{"type":"heading1","text":"otro uid"}],
"description":[{"type":"paragraph","text":"descripción"}]}}
],
"version":"3f9f504",
"license":"All Rights Reserved"
}
Two things to notice in the body. First, every text field is a rich-text array of typed spans, not a string — [{"type":"heading1","text":"otro uid","spans":[]}]. That's Prismic's structured-text model; it's how they keep formatting decoupled from rendering, but it means even a plain headline costs you a `.map()` in JSX. Second, x-ratelimit-limit: 200 (per minute) and x-ratelimit-remaining ticks down on the response headers. You can see budget usage on every request, which is genuinely useful.
Friction 2 — the error envelope is honest, and that helps
We tried two failure modes against the same repository. The error responses are short and the messages are usable:
$ curl -sSL -D - "https://example-prismic.cdn.prismic.io/api/v2/documents/search?ref=invalid_ref"
HTTP/2 404
content-type: application/json
{"type":"api_notfound_error","message":"Ref not found. Ensure you have the correct ref and try again. Master ref is: W3ROxyYAAPeuMvvg"}
$ curl -sSL -D - "https://example-prismic.cdn.prismic.io/api/v2/documents/search"
HTTP/2 400
{"type":"api_validation_error","message":"Please specify ref"}
$ curl -sSL -D - "https://this-repo-does-not-exist-xyz.cdn.prismic.io/api/v2"
HTTP/2 404
content-length: 0
x-prismic-region: eu-west-2
x-prismic-version: 6
The bad-ref response not only tells you the ref is wrong, it tells you what the master ref currently is. That means a developer who hand-pasted a stale ref can recover from a single curl, no SDK debug session needed. It's the friendliest error envelope of any headless CMS we've poked at this week, and it costs Prismic almost nothing — they had to put the master ref into the response anyway. Worth copying.
The bogus-subdomain response is also worth flagging — empty body, but the headers (x-prismic-region, x-prismic-version) come through. That confirms the request hit Prismic's edge, was routed by subdomain, and rejected at the application layer rather than DNS-failing. Their wildcard is *.cdn.prismic.io, all routed to the same gateway.
Friction 3 — the Slice Machine page admits Slice Machine is being replaced
prismic.io/docs/slice-machine — 2026-05-07. The yellow callout in the middle is the news.Slice Machine is the feature Prismic has been pitching for years: a CLI you run locally, you build a slice as a React/Vue/Svelte component, the CLI introspects the props, generates a JSON schema, and pushes it to your Prismic repository. Designers see "Hero with image left", developers see <Hero/>, content editors see a slice they can drop into any page. It's a real differentiator vs Storyblok's nested-bloks model — Prismic's slices are component-shaped from day one.
The friction, on the test date, is what the Slice Machine documentation page itself says at the top:
"New users have access to the Type Builder, a cloud-based content modeling tool that replaces Slice Machine. New projects should use the Type Builder."
Translation: the local-first CLI that defined Prismic's developer story is being shifted into legacy mode for new repositories. The Type Builder is a dashboard tool — schema lives in Prismic's cloud, not your git history. If you start a new project today and follow the on-rails flow, you'll model your content in their UI, not in your codebase. If you specifically wanted "schema as code", you have to opt out by installing Slice Machine into an existing repo and pointing it at a new Prismic repository.
This is a real pivot, and we don't have a strong opinion on it yet — Type Builder might be a better experience for non-technical content modellers, and Slice Machine is by all accounts still maintained. But the docs page that should be selling Slice Machine to new readers is instead asking them to use a different tool. That's worth knowing before you base a tooling decision on a 2024 Prismic blog post about "schemas in your git history".
Friction 4 — the Content API needs a typed-text mental model
prismic.io/docs/api (Fetch Content section) — 2026-05-07. @prismicio/client is the official SDK; the typed-text shape lives behind it.If you've worked with Contentful or Sanity, the Prismic Content API will feel slightly off in one specific way: everything text is a structured-text array. A field marked "Title" in the dashboard does not return "Hello" — it returns [{"type":"heading1","text":"Hello","spans":[]}]. Every paragraph is an array. Every link is an object with a link_type. The official client (@prismicio/client) wraps this with helpers (asText(), asHTML(), asLink()), and that's where most teams live; raw API consumption is for people who actively want to render Prismic's structured-text format themselves.
The trade-off is real. Structured text means a single field can carry inline links, bold spans, and image references without escaping or stringifying — useful for a CMS that wants to be the canonical source for marketing copy. The cost is that "show me the title" is never one property access; it's asText(doc.data.title) at minimum, and you need the SDK at hand to do it idiomatically. New developers reach for doc.data.title, get an array, and write a render-blank bug.
Friction 5 — the signup gate is light, but the path forward is opinionated
prismic.io/dashboard/signup — 2026-05-07. Email or GitHub. No company-name field, no role dropdown.For comparison: Storyblok's signup has a required Company Name field. Prismic's signup is the opposite extreme — one email field, one button, GitHub OAuth. After you confirm the email, you pick a repository name, you pick a starter (Next.js, Nuxt, SvelteKit, blank), and the dashboard runs you through a tutorial that scaffolds a local project. The on-rails flow assumes you have Node, you have a terminal, and you'll npx something within a few minutes. Indie devs and weekend-project builders won't bounce here. Marketing-led teams who want to click around the dashboard with no code might find the absence of a "skip the tutorial" button mildly confusing.
Honest comparison — one row each
One row per CMS, picked for the dimension that actually moves the decision:
| Tool | Free tier headline | The thing it's better at | The thing it's worse at |
|---|---|---|---|
| Prismic | 1 repo, generous Free, $150 to scale | Slices — component-shaped content models that match how a frontend team actually thinks about pages | Slice Machine is being soft-deprecated in favour of Type Builder; structured-text arrays surprise new readers |
| Storyblok | 1 seat, 100k API req, 2 locales | Visual Editor — clicking on the live page to edit a heading is genuinely smooth when it works | Nested bloks model is its own learning curve; localStorage friction in private-browsing iframes |
| Contentstack | No public free tier — sales call required | Battle-tested at large enterprise; broad localisation and workflow features | Pricing opacity; the funnel is built for procurement, not for an evaluating engineer |
| Sanity | 3 users, 10k docs, generous bandwidth | Studio is a React app in your repo — schema is code, version-controlled, no CLI sync step | No native Visual Editor; Presentation exists but you wire it up |
If your team thinks in components and wants the content model to be shaped like the frontend, Prismic's slice model is closer to that than anything else in this table — even with the Type Builder transition in flight. If you want the schema to live in your repo with no extra ceremony, Sanity does that more cleanly. If your team's job description is "click on the page to edit it", Storyblok is harder to beat.
Things we'd change in the docs
- Resolve the Slice Machine vs Type Builder story up front. Right now the Slice Machine page tells you to use the other tool, and the marketing site still leads with Slice Machine vocabulary. Pick one canonical name for new readers in 2026.
- Document the master-ref handshake in the quickstart, not just the API reference. "Why do I need two requests to read a page?" is the first question a curl-curious developer asks, and the docs assume you'll use the SDK before you understand why.
- Show the rate-limit headers in a table somewhere visible.
x-ratelimit-remainingis on every response, but the docs talk about rate limits as a number in a list rather than a runtime signal you can read. - Add a "your title is an array, here's why" sidebar to the Fetch Content page. Structured text is the right call but it's the first wall a new reader hits, and explaining it in line beats sending them to the SDK helpers reference.
Where this fits
One short, honest write-up per CMS we evaluate. Adjacent: Storyblok scout, Contentstack scout, Ghost 5.x first-deploy notes, Strapi 5 self-host scout, Directus on a single VPS. SimpleReview is the Chrome extension that turns whatever element you click on a broken admin into a draft code-fix PR — including the slice-builder views inside the Prismic dashboard, once you're past signup.