A WenHunt Group platform · Headless CMS · API-first
One backend. Every front-end.
Publishd is the content backend behind every product WenHunt Group ships.
One content model per product, one dashboard for every editor, and one fast API
serving every app, site and surface in the group.
No boilerplate CMS to install, no database to run, no per-app rebuild. Define the shape, fill it in, fetch it anywhere.
01 / MODEL
Model your content
Define the shape your product actually needs — events, venues, listings, articles, offers. Fields, relations, validation and localisation, versioned per project and changed without a migration.
Editors work in one place across every project they have access to. Draft, upload media, request review, schedule for 6am Saturday, hit publish. Nobody waits on a deploy.
Draft → In review → Scheduled → Live Sat 06:00 BST · queued by @ellie Rollback to any previous version
03 / FETCH
Pull it anywhere
Hit the REST or GraphQL API with a project key and get clean, typed JSON back — cached at the edge. Same content, same shape, whether it's a Next.js site, a SwiftUI app or a static build.
GET /v1/entries?type=event x-publishd-project: localos → 200 · 41 ms · edge cached
Capabilities
Everything a content backend owes you.
The parts you'd otherwise rebuild for every product — built once, shared across all of them.
Content models per project
Every project defines its own schema. A town app's "venue" and a marketplace's "listing" live side by side without leaking into each other — and evolve independently.
One API for every front-end
REST and GraphQL from the same content, with typed SDKs for JavaScript, Swift and Kotlin. Edge-cached responses, webhooks on publish, and previews for unreleased drafts.
Media library
Upload once, use everywhere. Automatic resizing, WebP and AVIF conversion, focal-point cropping and CDN delivery — with alt text and rights held against the asset, not the page.
Scheduling & workflows
Queue content for a date and time, embargo it until an announcement lands, or route it through review first. Full version history, side-by-side diffs and one-click rollback.
Roles & permissions
Scoped API keys per project and environment. Roles from read-only contributor to owner, granular down to a single content type, plus SSO and an audit log of who changed what.
Multi-tenant workspaces
Run every brand in the group from one workspace. Shared infrastructure, media and monitoring; isolated content, keys and editors. Add the next product in minutes, not sprints.
API-first
Real responses, in about 40 ms.
The dashboard is a client of the same public API you build against. Nothing is hidden behind it.
Scoped keys — one project's key can never read another's content.
Filter, sort, paginate and expand relations in a single request.
Edge-cached globally, invalidated the moment an editor publishes.
Types generated from your schema, so a field rename fails at build.
# Fetch the next two events for a town appcurl https://api.publishd.io/v1/entries \
-G -d type=event -d limit=2 -d sort=starts_at \
-H "x-publishd-project: localos" \
-H "authorization: Bearer pub_live_••••"HTTP/2 200 · 41ms · x-publishd-cache: HIT
{
"data": [
{
"id": "evt_9wKq2n",
"type": "event",
"title": "Late Night At The Museum",
"starts_at": "2026-08-08T19:30:00+01:00",
"venue": { "name": "City Museum", "lat": 51.5072 },
"hero": "https://cdn.publishd.io/localos/museum.avif?w=1200",
"status": "live"
},
{ "id": "evt_4tBm7d", "title": "Riverside Market", … }
],
"meta": { "total": 37, "cursor": "eyJvIjoyfQ" }
}
// npm i @publishd/clientimport { createClient } from"@publishd/client";
const publishd = createClient({
project: "localos",
token: process.env.PUBLISHD_TOKEN,
});
const { data, meta } = await publishd.entries.list({
type: "event",
limit: 2,
sort: "starts_at",
expand: ["venue"],
});
data[0].title; // "Late Night At The Museum"
data[0].venue.name; // "City Museum"
meta.total; // 37// Types are generated from your schema:// npx publishd types --project localos
// Swift Package: github.com/publishd/publishd-swiftimport Publishd
let publishd = Publishd(
project: "localos",
token: Secrets.publishdToken
)
let events: [Event] = try await publishd.entries(
of: Event.self,
limit: 2,
sort: .ascending("starts_at"),
expand: ["venue"]
)
events.first?.title // "Late Night At The Museum"
events.first?.venue.name // "City Museum"// Responses are cached on device and revalidated// from the publish webhook, so the app opens instantly.
REST · GraphQL · Webhooks · Preview API
Built with Publishd
Two products that share nothing but a backend.
Different content models, different audiences, different front-ends — one CMS, one set of infrastructure, one platform team.
L
LocalOS
City app platform · iOS, Android, Web
LocalOS runs branded town apps and websites where every place gets its own identity,
its own editors and its own local content. Each town is a separate
Publishd project with its own model for venues, events and offers, and its own keys. They
share one media library, one scheduling engine and one dashboard, so launching the next town
is a configuration change rather than a codebase.
Turnstile models its content nothing like a town app does — and that's the point. It defines
its own types, its own roles and its own publishing rules inside the same platform, pulling
everything through the same API its team already knows. Adding a second product meant a new
project and a new key, not a second CMS to run, patch and pay for.
Publishd isn't sold by the seat. It's the platform WenHunt Group runs its own products on — so every product inherits the same infrastructure, the same guarantees and the same security posture.
99.95%Uptime target
~40 msp50 API response
3Environments per project
1Platform team behind it
Infrastructure
Managed Postgres with point-in-time recovery, object storage for media, and a CDN in front of every read path. Provisioned once, shared by every project on the platform.
Environments
Development, staging and production per project, each with its own keys and content. Promote a schema change through staging without touching anything live.
Data & residency
Content and media stored in UK and EU regions. Nothing leaves the region it was written to, which keeps every product in the group on the same footing for GDPR.
Backups & recovery
Continuous backups with 30-day point-in-time restore. Every publish is versioned, so rolling back a bad edit never means restoring a database.
Security & access
Group SSO, scoped API keys per project and environment, granular roles, and a full audit log. Encrypted in transit and at rest, with quarterly key rotation.
Observability
Per-project request, latency and error dashboards, webhook delivery logs, and alerting straight into the platform team's on-call rota.
Bringing a new product onto Publishd?
If you're building something new inside WenHunt Group, start here rather than standing up another CMS. Tell the platform team what you need to model and we'll have a project, API keys and a staging environment ready for you the same day.