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 add live content to 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}.jsonCommon query 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 default 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, and people and venues sort alphabetically. |
The available filters vary by content type. Pages accept slug and relativePath. Posts accept slug plus blog, category, tag, author, and exclusion filters. Most other content lists accept slug. Event lists also accept depth (0 to 5), select, and event-specific filters. Translated fields come back in your site's configured language automatically.
Response
A standard paginated list contains a docs array plus pagination metadata. The depth parameter expands related records inline.
{
"docs": [
{
"id": "000000000000000000000005",
"title": "Remarkable Theatre News",
"slug": "remarkable-theatre-news",
"posts": {
"docs": [
{ "id": "000000000000000000000004", "title": "How Moonclock was made", "slug": "making-moonclock" }
]
}
}
],
"totalDocs": 1,
"limit": 10,
"totalPages": 1,
"page": 1,
"pagingCounter": 1,
"hasPrevPage": false,
"hasNextPage": false,
"prevPage": null,
"nextPage": null
}List endpoints return a public summary chosen for that content type. Detail endpoints can return more fields. Open the matching reference in the Fields column above for the template-facing model, but do not assume every template field is present in a list response.
Rich-text fields come with a rendered-HTML companion alongside the plain value. For example, richTitle_html and richDescription_html accompany title and description, while richName_html accompanies names 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 reference large records. These need only 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": { ... } }. A detail response can contain more fields than its list summary. 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 does not have access to it. |
500 | Server error. |
Field selection
Event lists accept ?select= with a comma-separated list of dotted field paths. The response always includes the full pagination wrapper. The select parameter narrows only the items inside docs.
/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');
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.