# Records

Records are the content half of the Objects module. The list endpoint is the only paginated endpoint on the Objects surface and supports sorting, free-text search, and per-property filtering over the record values. Both endpoints require the `objects:read` scope, and record `values` only ever contain active (non-archived) property keys.

## GET /v1/api/objects/types/{key}/records

Paginated list of records of one object type, addressed by the type's key (from `GET /v1/api/objects/types`).

### Path parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `key` | string | Yes | The object type key, for example `faq`. |

### Query parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `sort` | string | No | Sort column: `created_at` or any active property key. Prefix with `-` for descending. Default `-created_at`. `number` and `money` properties sort numerically, `date` properties sort as dates; records without a value for the property sort last. |
| `q` | string | No | Case-insensitive substring search, ORed across all `text` and `textarea` properties of the type. Ignored (matches everything) when the type has no text properties. |
| `filter[{propertyKey}]` | string | No | Exact-match filter on one property. Booleans accept `true`, `false`, `1`, `0`. `select` matches the option string. Repeatable for multiple properties; multiple filters combine with AND. |
| `filter[{propertyKey}][from]` | string | No | Lower bound (inclusive). Only for `number`, `money`, and `date` properties. Dates as `YYYY-MM-DD`, money in cents. |
| `filter[{propertyKey}][to]` | string | No | Upper bound (inclusive). Same types and formats as `from`. `from` and `to` can be combined or used alone. |
| `per_page` | integer | No | Page size. Default 25, clamped to the range 1 to 100. |
| `page` | integer | No | Page number, default 1. |

```bash title="Request"
curl --globoff "https://api.borkol.com/v1/api/objects/types/faq/records?sort=-created_at&q=delivery&filter[category]=shipping&per_page=10" \
  -H "Authorization: Bearer {api_key}"
```

```javascript title="Request (JS)"
const params = new URLSearchParams({
  sort: "-created_at",
  q: "delivery",
  "filter[category]": "shipping",
  per_page: "10",
});
const res = await fetch(
  `https://api.borkol.com/v1/api/objects/types/faq/records?${params}`,
  { headers: { Authorization: `Bearer ${apiKey}` } },
);
const { data, meta } = await res.json();
```

Status: `200 OK`. The response uses the standard Laravel pagination envelope: `data` (the records), `links` (`first`, `last`, `prev`, `next` page URLs, `null` where absent), and `meta` (`current_page`, `from`, `last_page`, `links`, `path`, `per_page`, `to`, `total`).

```json title="Response"
{
  "data": [
    {
      "id": "5e6f7a8b-9c0d-4e1f-a2b3-c4d5e6f7a8b9",
      "values": {
        "name": "How long does delivery take?",
        "answer": "Orders ship within 2 business days.",
        "category": "shipping"
      },
      "created_at": "2026-08-01T09:15:00.000000Z"
    }
  ],
  "links": {
    "first": "https://api.borkol.com/v1/api/objects/types/faq/records?page=1",
    "last": "https://api.borkol.com/v1/api/objects/types/faq/records?page=3",
    "prev": null,
    "next": "https://api.borkol.com/v1/api/objects/types/faq/records?page=2"
  },
  "meta": {
    "current_page": 1,
    "from": 1,
    "last_page": 3,
    "links": [
      { "url": null, "label": "&laquo; Previous", "active": false },
      { "url": "https://api.borkol.com/v1/api/objects/types/faq/records?page=1", "label": "1", "active": true },
      { "url": "https://api.borkol.com/v1/api/objects/types/faq/records?page=2", "label": "2", "active": false },
      { "url": "https://api.borkol.com/v1/api/objects/types/faq/records?page=3", "label": "3", "active": false },
      { "url": "https://api.borkol.com/v1/api/objects/types/faq/records?page=2", "label": "Next &raquo;", "active": false }
    ],
    "path": "https://api.borkol.com/v1/api/objects/types/faq/records",
    "per_page": 10,
    "to": 10,
    "total": 25
  }
}
```

### Errors

- `404` when no object type has that key.
- `422` with `errors.sort` `["Cannot sort by {column}."]` when `sort` names something that is neither `created_at` nor an active property key.
- `422` with `errors.filter` `["Cannot filter by {field}."]` when a filter names an unknown or archived property, or passes an array (`from`/`to`) to a property that is not `number`, `money`, or `date`.
- `422` with `errors.filter` `["Invalid filter value for {field}."]` when a `number` or `money` value or bound is not numeric, or a `date` value or bound is not a valid `YYYY-MM-DD` date.
- `403` `{"error":"Module not enabled: objects"}` and `403` `{"message":"Invalid ability provided."}` for module and scope failures.

## GET /v1/api/objects/records/{id}

Fetch a single record by id. This works across all object types; you do not need to know the type key. `values` contains only active property keys. A `sections` property holds the full section stack verbatim; see the [Objects concept page](./index) for the section instance shape, including locale-map values on localized fields.

### Path parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | string (uuid) | Yes | The record id. |

```bash title="Request"
curl https://api.borkol.com/v1/api/objects/records/6f7a8b9c-0d1e-4f2a-b3c4-d5e6f7a8b9c0 \
  -H "Authorization: Bearer {api_key}"
```

Status: `200 OK`.

```json title="Response"
{
  "data": {
    "id": "6f7a8b9c-0d1e-4f2a-b3c4-d5e6f7a8b9c0",
    "values": {
      "name": "About us",
      "body": [
        {
          "_key": "sec_a1b2c3d4e5f60718293a4b5c",
          "type": "hero",
          "look": "default",
          "v": 1,
          "visible": true,
          "data": {
            "title": { "en": "Welcome to our shop" },
            "image": "2b3c4d5e-6f7a-4b8c-9d0e-1f2a3b4c5d6e",
            "cta": { "url": "/products", "label": "Shop now" }
          }
        }
      ]
    },
    "created_at": "2026-07-20T14:05:33.000000Z"
  }
}
```

### Errors

- `404` when the record does not exist for this store.
- `403` module and scope errors as above.
