Basker Docs

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 returns a paginated array, and a detail endpoint 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 typeListDetailFields
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}.json

Common query parameters

ParameterTypeDefaultDescription
pageinteger1Page number to return. The maximum is 1000. Basker reduces a higher value to 1000.
limitintegervariesPage size. The maximum is 500. Basker reduces a higher value to 500. Most types default to 10, pages default to 100, and events default to 500.
sortstringvariesField 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.

Pages accept slug and relativePath. Posts accept slug, and blog=<blog slug> to list one blog's posts. Most other content lists accept slug. Event lists also accept depth (0 to 5) and select. For date, relationship, and custom attribute filters, see Filtering.

Every endpoint accepts locale. Without it, translated fields come back in the site's default language. Pass ?locale=cy (or another language the site offers) for another language.

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",
            "url": "/posts/making-moonclock",
            "publishDate": "2030-05-01T09:00:00.000Z",
            "authors": []
          }
        ],
        "hasNextPage": false
      }
    }
  ],
  "totalDocs": 1,
  "limit": 10,
  "totalPages": 1,
  "page": 1,
  "pagingCounter": 1,
  "hasPrevPage": false,
  "hasNextPage": false,
  "prevPage": null,
  "nextPage": null
}

In /api/blogs.json and /api/blogs/{id}, each blog's posts is a paginated list of its published posts, newest first. It holds at most 10 posts. Add all=true to get every post, or use /api/posts.json?blog=<blog slug> to page through them. Each post there carries title, slug, url, publishDate, updatedAt, authors, image, description, and categories. Use url for links rather than building the path yourself.

Records that have saved template settings carry them at theme.settings, for example theme.settings.prefix on an item in /api/events.json. There is no top-level copy of those settings. The theme key is missing when a record has no saved template settings, so check it before you read from it.

List endpoints return a public summary chosen for that content type. Detail endpoints can return more fields. 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. Do not assume that 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. richName_html accompanies names on people. Use the _html value when you want ready-to-render markup. Use the plain value for link text and aria-label attributes.

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.

SettingResponse shape
Full recordReturns the expanded related record when depth expands that relationship.
SummaryReturns a compact object with identifying fields such as id, title, name, label, slug, or url.
Reference onlyReturns 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.

Filtering

Five list endpoints accept filter parameters: /api/events, /api/event-instances, /api/posts, /api/organizations, and /api/smart-collections. The other list endpoints in the table above accept page, limit, sort, and their own slug lookup only.

Filters combine with AND. A request that sets a date range, a venue, and a category returns only the records that match all three.

Filtering happens at the edge

Basker caches a filtered list response the same way it caches an unfiltered one. Your site can send a narrow query straight from the browser, or from a server that renders your pages. The response still comes from the edge cache. See Caching.

Shortcut parameters

Each filterable endpoint accepts a short parameter for the relationships that themes query most.

EndpointParameterMatches
/api/eventsvenueIdThe venue set on the event.
/api/eventsseasonIdThe season set on the event.
/api/eventsseriesIdOne of the series set on the event.
/api/eventscompanyIdThe company set on the event.
/api/eventsidsA comma-separated list of event IDs.
/api/event-instanceseventIdThe parent event.
/api/event-instancesvenueIdThe venue set on the instance.
/api/event-instancesseriesIdOne of the series set on the instance.
/api/event-instancesseasonIdThe season set on the parent event.
/api/postsblogId, authorId, categoryId, tagIdOne related record each.
/api/postsauthorIds, categoryIdsComma-separated lists. A post matches when it has any one of the values.
/api/organizationstypeThe organization type.
/api/events.json?venueId=000000000000000000000003
/api/event-instances.json?venueId=000000000000000000000003&limit=50

Field filters

For any other field, use a where parameter. The pattern is where[field][operator]=value.

OperatorMatches
equals, not_equalsAn exact value, or anything other than it.
in, not_inAny value in a comma-separated list.
greater_than, greater_than_equalValues above a number or a date.
less_than, less_than_equalValues below a number or a date.
like, containsText that includes the value.
existsRecords where the field is set (true) or empty (false).

Dates take an ISO 8601 timestamp. This is the query behind a month view in a calendar:

/api/event-instances.json
  ?where[startDate][greater_than_equal]=2026-10-01T00:00:00.000Z
  &where[startDate][less_than]=2026-11-01T00:00:00.000Z

Group conditions with and and or when one field is not enough:

/api/events.json?where[or][0][title][like]=mozart&where[or][1][description][like]=mozart

Custom attribute filters

Filter on a custom attribute with attributeWhere[custom.{key}][{operator}]=value. The custom. prefix is optional. Use attributeWhere[{key}] when the attribute belongs to a collection block.

/api/events.json?attributeWhere[custom.category][in]=bookbug,family-fun

attr[{key}]=value is a shorthand for an equals match on the same attribute:

/api/events.json?attr[category]=bookbug

Attributes that hold text, numbers, dates, checkboxes, and select values accept equals, not_equals, in, contains, like, exists, greater_than, greater_than_equal, less_than, and less_than_equal. Attributes that link to another record accept equals, in, and contains only.

Pass in values as one comma-separated list. Basker matches values exactly, so send the stored value rather than the editor label.

What a filter cannot reach

Filters narrow the public list. They never widen it. Every list response stays inside these limits, whatever the query asks for.

  • The list returns published records only. Drafts and scheduled records stay out until they publish.
  • /api/event-instances excludes instances that editors have hidden.
  • /api/event-instances excludes instances before the start of today unless the request sets showPast=true.
  • /api/events returns only events that have not finished. It has no showPast parameter. To read past dates, query /api/event-instances with showPast=true.

A date filter does not override showPast

A request to /api/event-instances for a range in the past returns an empty list unless it also sets showPast=true. The two conditions combine with AND.

Worked example

This request asks a "what is on" page for one venue, one month, and two categories:

const params = new URLSearchParams({
  'where[startDate][greater_than_equal]': '2026-10-01T00:00:00.000Z',
  'where[startDate][less_than]': '2026-11-01T00:00:00.000Z',
  venueId: '000000000000000000000003',
  'attributeWhere[custom.category][in]': 'bookbug,family-fun',
  select: 'startDate,event.title,event.url,venue.title',
  limit: '200',
});

const res = await fetch(`/api/event-instances.json?${params}`);
const { docs } = await res.json();

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

StatusMeaning
400The id is missing or not a valid identifier.
404No record with that ID exists, or your site does not have access to it.
500Server error.

Field selection

/api/events and /api/event-instances 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.url

Use 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. Public responses carry Cache-Control: public, s-maxage=3600, max-age=60, stale-while-revalidate=86400, stale-if-error=86400.

Keep query parameters stable across visitors so responses stay cacheable. A filtered URL caches as well as an unfiltered one. Build the same query for every visitor who sees the same view. Avoid cache-busters and per-visitor timestamps unless you need a fresh response.

Two cases change the header. A password-protected site returns a private response that only the browser caches. A preview request is never cached.

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 custom data.

On this page