> ## Documentation Index
> Fetch the complete documentation index at: https://docs.keebai.com/llms.txt
> Use this file to discover all available pages before exploring further.

# GET /v1/blocks

> List every block in the project, attached to an assistant or not, with metadata and no content.

The project's whole block catalogue. Blocks are not owned by an assistant: they live here and any number of assistants can reference them, so this is where you look for something to reuse.

Metadata only, no content — for that, [read one block's content](/dev/endpoints/blocks-content-get).

## Endpoint

```
GET https://api.keebai.com/v1/blocks
```

## Required scope

`assistants:read`

## Headers

| Header          | Required | Value                    |
| --------------- | -------- | ------------------------ |
| `Authorization` | Yes      | `Bearer kbai_pk_<token>` |

## Query parameters

| Parameter          | Type      | Default | Description                                  |
| ------------------ | --------- | ------- | -------------------------------------------- |
| `type`             | `string`  | —       | One of the twelve block types.               |
| `family`           | `string`  | —       | `identity`, `instructions` or `information`. |
| `include_archived` | `boolean` | `false` | Include archived blocks.                     |
| `limit`            | `integer` | `50`    | Records per page, 1–200.                     |
| `offset`           | `integer` | `0`     | Records to skip.                             |

## Example request

<CodeGroup>
  ```bash curl theme={null}
  curl -s "https://api.keebai.com/v1/blocks?family=instructions&limit=50" \
    -H "Authorization: Bearer kbai_pk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
  ```

  ```js JavaScript theme={null}
  const params = new URLSearchParams({ family: "instructions", limit: "50" });
  const resp = await fetch(`https://api.keebai.com/v1/blocks?${params}`, {
    headers: { Authorization: `Bearer ${process.env.KEEBAI_API_TOKEN}` },
  });
  const { data, has_more } = await resp.json();
  ```

  ```python Python theme={null}
  import os, requests

  resp = requests.get(
      "https://api.keebai.com/v1/blocks",
      headers={"Authorization": f"Bearer {os.environ['KEEBAI_API_TOKEN']}"},
      params={"family": "instructions", "limit": 50},
      timeout=10,
  )
  resp.raise_for_status()
  page = resp.json()
  ```
</CodeGroup>

## Response

### 200 OK

```json theme={null}
{
  "data": [
    {
      "_id": "6650bbbb2222cccc3333dddd",
      "type": "steps",
      "family": "instructions",
      "name": "Reserva",
      "current_version_id": "6650ffff4444aaaa5555bbbb",
      "is_archived": false,
      "content_writable": true,
      "created_at": "2026-07-20T14:02:11.870Z",
      "updated_at": "2026-07-26T09:44:03.512Z"
    }
  ],
  "limit": 50,
  "offset": 0,
  "has_more": false
}
```

### 401 Unauthorized

Missing, invalid, revoked, or expired token.

### 403 Forbidden

The token does not have the `assistants:read` scope.

### 502 Bad Gateway

The assistant service is unreachable.

## Operational notes

* **There is no `total`, and that is deliberate.** The upstream store exposes no count for blocks, so rather than return the length of the current page as if it were the size of the set — which would make a client stop paginating early — the response carries `has_more`. Page until it is `false`.
* **Archived blocks are hidden by default but still active.** `include_archived=false` only affects this listing: an archived block that is still attached to an assistant keeps rendering into its prompt. To take it out of an assistant, [detach it](/dev/endpoints/assistants-block-detach).
* **`content_writable: false` marks the five catalogue types** — `product_info`, `store_info`, `reservation_info`, `tables_info`, `tags`. You can read, rename and archive them here; [saving their content](/dev/endpoints/blocks-content-save) returns `409`.
* **Scoped to the token's project.** A block created under another project of the same company does not appear and cannot be read by id.
* **A block with `current_version_id: null` has never been saved.** Reading its content returns `404 BLOCK_CONTENT_NOT_FOUND`.


## OpenAPI

````yaml GET /v1/blocks
openapi: 3.0.0
info:
  title: Keebai Public API
  description: Superficie pública REST autenticada con Personal Access Tokens (PAT).
  version: 1.0.0
  contact: {}
servers:
  - url: https://api.keebai.com
    description: Production
security: []
tags: []
paths:
  /v1/blocks:
    get:
      tags:
        - blocks
      summary: Listar bloques del proyecto
      description: >-
        Devuelve todos los bloques del proyecto, esten adjuntos a un asistente o
        no, con metadata y sin contenido. Un mismo bloque se puede reusar en
        varios asistentes.
      operationId: PublicBlocksController_list
      parameters:
        - name: limit
          required: false
          in: query
          schema:
            minimum: 1
            maximum: 200
            default: 50
            type: number
        - name: offset
          required: false
          in: query
          schema:
            minimum: 0
            default: 0
            type: number
        - name: type
          required: false
          in: query
          schema:
            type: string
            enum:
              - personification
              - objective
              - response_format
              - steps
              - cases_possible
              - do_not
              - product_info
              - store_info
              - reservation_info
              - tables_info
              - tags
              - response_policy
        - name: family
          required: false
          in: query
          schema:
            type: string
            enum:
              - identity
              - instructions
              - information
        - name: include_archived
          required: false
          in: query
          description: >-
            Incluye los bloques archivados. Un bloque archivado sigue rindiendo
            en el prompt de los asistentes que lo tienen adjunto.
          schema:
            type: boolean
            default: false
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PublicBlockListResponseDto'
      security:
        - PAT: []
components:
  schemas:
    PublicBlockListResponseDto:
      type: object
      properties:
        limit:
          type: number
        offset:
          type: number
        has_more:
          type: boolean
          description: Si hay al menos una pagina mas despues de esta.
        data:
          type: array
          items:
            $ref: '#/components/schemas/PublicBlockDto'
      required:
        - limit
        - offset
        - has_more
        - data
    PublicBlockDto:
      type: object
      properties:
        _id:
          type: string
        type:
          type: string
          enum:
            - personification
            - objective
            - response_format
            - steps
            - cases_possible
            - do_not
            - product_info
            - store_info
            - reservation_info
            - tables_info
            - tags
            - response_policy
        family:
          type: string
          enum:
            - identity
            - instructions
            - information
          description: >-
            Se deriva del tipo y determina en que seccion del prompt entra el
            bloque. Es de solo lectura.
        name:
          type: string
        current_version_id:
          type: string
          nullable: true
          description: >-
            Version vigente del bloque. Su contenido se lee en GET
            /v1/blocks/{id}/content.
        is_archived:
          type: boolean
        content_writable:
          type: boolean
          description: >-
            Si el contenido de este bloque se puede editar por API. Los tipos de
            catalogo son de solo lectura porque su escritura depende de una
            sincronizacion de funciones que vive en el portal.
        created_at:
          type: string
        updated_at:
          type: string
      required:
        - _id
        - type
        - family
        - name
        - current_version_id
        - is_archived
        - content_writable
        - created_at
        - updated_at
  securitySchemes:
    PAT:
      scheme: bearer
      bearerFormat: kbai_pk_<hex>
      type: http
      description: >-
        Personal Access Token con prefijo `kbai_pk_`. Generar desde el portal
        con permiso `developer.manage_tokens`.

````