Data Access

Reading Data

Read items from your collections via REST or SDK.

Get All Items

Returns a list of items from a collection. By default, results are limited to 100 items and the API response is wrapped in a { data: [...] } envelope (the SDK unwraps this automatically).

Eligible repeated reads can reuse cached results instead of querying the connected data source again.

const articles = await client.Articles.readMany({
  fields: ['id', 'title', 'status'],
});
Tip
By default, results are limited to 100 items. Use limit and offset to paginate — see Sorting & Pagination.

Get a Single Item by ID

Fetches a single item by its primary key. Append the key value to the collection URL in REST, or pass it as the key property in the SDK.

const article = await client.Articles.readOne({
  key: 1,
  fields: ['id', 'title', 'content'],
});

Get the First Matching Item

Combine limit=1 with a filter and sort to return a single matching item. In REST you must extract the first element from the returned array. The SDK provides a dedicated readFirst() method that returns T | null directly.

const latest = await client.Articles.readFirst({
  fields: ['id', 'title'],
  filter: { status: { _eq: 'published' } },
  sort: [{ created_at: { direction: 'desc' } }],
});
SDK
The SDK provides readFirst() as a convenience for this pattern, returning T | null directly. It accepts the same parameters as readMany but automatically sets limit: 1 and unwraps the single result.

Choose Which Fields to Return

Use the fields parameter to select only the fields you need. This reduces payload size and improves performance.

The SDK requests all top-level primitive fields when you omit fields. In REST requests, omitting fields selects no primitive fields, so pass it explicitly.

Use fields=* (REST) or fields: ['*'] (SDK) to explicitly request all top-level primitive fields:

const articles = await client.Articles.readMany({
  fields: ['*'],
});

Or select specific fields:

const articles = await client.Articles.readMany({
  fields: ['id', 'title', 'status'],
});

See Field Selection for related data, wildcards, and advanced patterns.


Request related items with the include parameter, alongside fields. Use fields to select primitive fields and include to name relations, each with its own query.

Name the relation under include and give it a fields list of its own:

const articles = await client.Articles.readMany({
  fields: ['id', 'title'],
  include: {
    author: { fields: ['name', 'email'] },
  },
});
To-Many Response Structure
When you include a to-many relation, the related items are wrapped in a { data: [...] } envelope — they are not returned as a bare array. This applies to both REST and SDK responses. The SDK unwraps only the top-level envelope and keeps the nested { data: [...] } wrapper.For example, requesting an author with their articles returns:
response.json
{
  "data": {
    "id": 1,
    "name": "Alice",
    "articles": {
      "data": [
        { "title": "First Post", "status": "published" },
        { "title": "Second Post", "status": "draft" }
      ]
    }
  }
}
This envelope structure allows future non-breaking additions such as inline pagination metadata (e.g., total count) on related collections.

A to-many relation accepts filter, sort, limit, and offset alongside its fields. In both REST and the SDK, place these parameters under the relation name in include:

const authors = await client.Authors.readMany({
  fields: ['id', 'name'],
  include: {
    posts: {
      fields: ['id', 'title'],
      filter: { status: { _eq: 'published' } },
      sort: [{ created_at: { direction: 'desc' } }],
      limit: 5,
    },
  },
});

See Field Selection for wildcards, nested includes, and advanced patterns.

SDK
The SDK unwraps the { data } envelope automatically. See Client Setup for the unwrapEnvelope option.

See Also

MonospaceThe governed API layer for every app, person, and agent.

Copyright © 2026 Monospace Inc.