End-to-End Journey
Every other page in this portal covers one feature in depth. This page walks through how they fit together, following a single realistic build from an empty project to a production integration a mobile team and a marketing team both rely on.
1. Model the content
Start in Creating A New Project, then define Collections and their Field Types - a Products collection with typed fields, say. This is the only step every later one depends on; nothing below requires redoing it.
2. Issue access for two different kinds of caller
Not every caller should authenticate the same way. From API Access:
- For the marketing site - a server you control - issue a static
read-only token. - For the mobile app - where individual users sign in - create a username/password credential instead, so the app can exchange a user's login for a short-lived access token and a rotating refresh token, rather than shipping a long-lived static token inside the app binary.
Before writing any client code, export a Postman collection from the same page: it already contains every route for the Products collection you just modeled, plus a Login/Refresh flow wired to fill in the token automatically. Import it and confirm the API behaves the way you expect before a single line of integration code exists.
3. Read content the way each client prefers
The marketing site's server-rendered pages fetch product lists with a simple GET against the REST v2 API. The mobile app, which needs a product, its category, and its images in one round trip without over-fetching, uses the GraphQL API instead - same token types, same underlying data, same cache, just a different request shape:
GET /public/v2/projects/:uuid/collections/products/content?sort=price:ascquery ProductDetail {
entry(collection: "products", id: 501) {
data
}
}4. Test which product copy actually converts
The marketing team is not sure whether a benefit-led or feature-led product description converts better. Instead of guessing, they set up a Content Experiment on the product entry, and the site requests it with ?experiment=1 - the same REST/GraphQL reads from step 3 now transparently resolve into whichever variant is winning, with no separate experimentation system to integrate.
5. React to changes instead of polling for them
Rather than re-fetching the catalog on a timer, the team registers a webhook for content.published and content.updated that notifies their search index and a Slack channel whenever a product changes. Delivery is signed, retried automatically, and logged - see Background Jobs for why that retry behavior is reliable rather than best-effort.
6. Let caching and the CDN do the rest
Reads are already served from a read-through cache, invalidated automatically by the same events the webhook above subscribes to. With a Cloudflare zone connected (see CDN & Media Pipeline), the same content change also purges the CDN in front of the API - so a product update shows up quickly everywhere, without the team writing any cache-invalidation code of their own.
7. Keep the mobile app's session alive
The mobile app's access token from step 2 expires after an hour. Rather than asking the user to log in again, the app calls /auth/refresh with its refresh token and receives a new access/refresh pair - and because refresh tokens rotate on every use, a leaked refresh token from an old build stops working the moment the legitimate app refreshes first.
Every piece is independently documented