Content endpoints
List and fetch published content — events, pages, posts, people, venues, and more — as JSON from your site
Most content types on your site expose a matching read-only JSON endpoint. They all share the same shape: a list endpoint that returns a paginated array, and a detail endpoint that returns one record by ID. Use them to pull live content into a theme or an embedded widget without a redeploy.
Event instances and search have their own pages because they take extra parameters. Everything else follows the contract on this page.
Available endpoints
| Content type | List | Detail | Fields |
|---|---|---|---|
| Events | /api/events | /api/events/{id} | Event |
| Pages | /api/pages | /api/pages/{id} | Page |
| Posts | /api/posts | /api/posts/{id} | Post |
| Blogs | /api/blogs | /api/blogs/{id} | Blog |
| People | /api/people | /api/people/{id} | Person |
| Venues | /api/venues | /api/venues/{id} | Venue |
| Organizations | /api/organizations | /api/organizations/{id} | Organization |
| Seasons | /api/seasons | /api/seasons/{id} | Season |
| Series | /api/series | /api/series/{id} | Series |
| Works | /api/works | /api/works/{id} | Work |
| Smart collections | /api/smart-collections | /api/smart-collections/{id} | Smart collection |
Each endpoint accepts the .json suffix interchangeably with the bare path (/api/events.json and /api/events). Responses contain the same published content that renders on your site for visitors.
List a content type
GET {your-domain}/api/{type}.jsonQuery parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
page | integer | 1 | Page number to return. |
limit | integer | varies | Page size. The default depends on the content type — most types default to 10; pages default to 100 and events to 500. |
sort | string | varies | Field to sort by. Prefix with - for descending (-publishDate). Defaults differ per content type — for example posts sort by newest first, people and venues sort alphabetically. |
depth | integer (0–5) | 2 | How deeply to expand related records (images, linked content). Higher values return more inline data; lower values are faster. |
select | string | — | Comma-separated dotted field paths to narrow the response. See Field selection. |
Some content types also accept relationship filters as query parameters — for example, events accept venueId, seasonId, seriesId, and companyId to return only matching records. Translated fields come back in your site's configured language automatically.
Response
A standard paginated list: a docs array plus pagination metadata. Related records are expanded inline according to depth.
{
"docs": [
{
"id": "67be2c1cb1d3f...",
"title": "News",
"slug": "news",
"posts": {
"docs": [
{ "id": "...", "title": "Our new season", "slug": "our-new-season" }
]
}
}
],
"totalDocs": 3,
"limit": 10,
"totalPages": 1,
"page": 1,
"pagingCounter": 1,
"hasPrevPage": false,
"hasNextPage": false,
"prevPage": null,
"nextPage": null
}The fields on each item match the record passed to that content type's template. Open the matching reference in the Fields column above to see what's available — for example, the Event template lists every field on an event.
Rich-text fields come with a rendered-HTML companion alongside the plain value — for example richTitle_html and richDescription_html next to title and description (and richName_html on people). Use the _html value when you want ready-to-render markup, and the plain value for things like link text or aria-labels.
Custom data relationships
Custom attributes and custom object fields can control how related records appear in public API responses. The setting is called Public API response in the editor.
| Setting | Response shape |
|---|---|
| Full record | Returns the expanded related record when depth expands that relationship. |
| Summary | Returns a compact object with identifying fields such as id, title, name, label, slug, or url. |
| Reference only | Returns only the related record ID, or an array of IDs for fields that allow multiple values. |
Use Summary or Reference only for relationships that point to large records but only need a title, URL, or lookup ID in the browser.
Get one record by ID
GET {your-domain}/api/{type}/{id}Returns the record wrapped in a doc key: { "doc": { ... } }. The record inside has the same field shape as items in the list response. The id comes from a list response or from a relationship field on another record.
Errors
| Status | Meaning |
|---|---|
400 | The id is missing or not a valid identifier. |
404 | No record with that ID exists, or your site doesn't have access to it. |
500 | Server error. |
Field selection
Pass ?select= with a comma-separated list of dotted field paths to drop everything else. The pagination wrapper is always returned in full; only items inside docs are narrowed.
/api/events.json?select=title,slug,image.urlUse field selection to keep payloads small when a grid or list only needs a few fields per record.
Examples
Fetch the latest posts for a feed:
const res = await fetch('/api/posts.json?limit=6&select=title,slug,image.url');
const { docs } = await res.json();Look up a single venue by ID:
const res = await fetch(`/api/venues/${venueId}`);
if (res.ok) {
const { doc: venue } = await res.json();
}Caching
When edge caching is enabled for your site, list responses can be served from the edge and refresh when an editor publishes a change. Keep query parameters stable across visitors so responses stay cacheable — avoid cache-busters or per-visitor timestamps unless you genuinely need a fresh response.
See also
- Event instances — performances, with date filtering and ticketing data.
- Search — full-text query across every content type at once.
- Custom objects — read your site's custom data.