> ## 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.

# POST /v1/assistants/{id}/blocks

> Attach one existing block to an assistant without touching the rest of its wiring.

Adds one block to the assistant's list, leaving every other block where it is. The cheap counterpart to [`PUT /v1/assistants/{id}/blocks`](/dev/endpoints/assistants-blocks-set), which replaces everything.

The block has to exist already. Create it with one of the [per-type endpoints](/dev/assistants/overview#block-types) first, or reuse one from [the catalogue](/dev/endpoints/blocks-list).

## Endpoint

```
POST https://api.keebai.com/v1/assistants/{id}/blocks
```

## Required scope

`assistants:write`

## Headers

| Header          | Required | Value                    |
| --------------- | -------- | ------------------------ |
| `Authorization` | Yes      | `Bearer kbai_pk_<token>` |
| `Content-Type`  | Yes      | `application/json`       |

## Path parameters

| Parameter | Type     | Description                  |
| --------- | -------- | ---------------------------- |
| `id`      | `string` | `ObjectId` of the assistant. |

## Body

| Field               | Type      | Required | Description                                                                       |
| ------------------- | --------- | -------- | --------------------------------------------------------------------------------- |
| `block_id`          | `string`  | Yes      | `ObjectId` of a block in the same company.                                        |
| `pinned_version_id` | `string`  | No       | Freeze this assistant to one version. Omit to follow the block's current version. |
| `order`             | `integer` | No       | Position in the prompt. Defaults to the end of the list.                          |

## Example request

<CodeGroup>
  ```bash curl theme={null}
  curl -X POST https://api.keebai.com/v1/assistants/6650a1b2c3d4e5f6a7b8c9d0/blocks \
    -H "Authorization: Bearer kbai_pk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
    -H "Content-Type: application/json" \
    -d '{ "block_id": "6650bbbb2222cccc3333ffff", "order": 2 }'
  ```

  ```js JavaScript theme={null}
  const base = "https://api.keebai.com/v1/assistants/6650a1b2c3d4e5f6a7b8c9d0";

  const resp = await fetch(`${base}/blocks`, {
    method: "POST",
    headers: {
      Authorization: `Bearer ${process.env.KEEBAI_API_TOKEN}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({ block_id: "6650bbbb2222cccc3333ffff", order: 2 }),
  });

  if (resp.status === 400) {
    const { error } = await resp.json();
    if (error.code === "ASSISTANT_DUPLICATE_IDENTITY_BLOCK") {
      // The assistant already has an identity block of this type.
    }
  }
  ```

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

  resp = requests.post(
      "https://api.keebai.com/v1/assistants/6650a1b2c3d4e5f6a7b8c9d0/blocks",
      headers={"Authorization": f"Bearer {os.environ['KEEBAI_API_TOKEN']}"},
      json={"block_id": "6650bbbb2222cccc3333ffff", "order": 2},
      timeout=10,
  )
  if resp.status_code == 400 and resp.json()["error"]["code"] == "ASSISTANT_DUPLICATE_IDENTITY_BLOCK":
      ...  # already has one of this type
  resp.raise_for_status()
  ```
</CodeGroup>

## Response

### 201 Created

The full assistant, same shape as [`GET /v1/assistants/{id}`](/dev/endpoints/assistants-get), with the block added.

### 400 Bad Request

A malformed `ObjectId` or an unknown property. `error.code` is `ASSISTANT_DUPLICATE_IDENTITY_BLOCK` when the assistant already holds an identity block of that type.

### 401 Unauthorized

Missing, invalid, revoked, or expired token.

### 403 Forbidden

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

### 404 Not Found

The assistant does not exist in the token's company and project, or `error.code` is `ASSISTANT_BLOCK_NOT_FOUND` because the block does not exist or belongs to another company.

### 502 Bad Gateway

The assistant service is unreachable.

## Operational notes

* **Attaching is not idempotent.** Calling it twice with the same `block_id` adds a second reference to the same block, which renders it twice in the prompt. Check the current list first, or use [`PUT`](/dev/endpoints/assistants-blocks-set), which is naturally idempotent.
* **Omitting `order` appends.** The block lands after everything currently attached. To insert in the middle you have to renumber, which means [`PUT`](/dev/endpoints/assistants-blocks-set).
* **The duplicate-identity check looks at the resulting list**, not just at what you sent, so it catches the case where the assistant already has a `personification` and you attach another.
* **One block, many assistants.** Attaching does not move or copy anything: the same block can be wired into any number of assistants, each with its own `order` and pin.


## OpenAPI

````yaml POST /v1/assistants/{id}/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/assistants/{id}/blocks:
    post:
      tags:
        - assistants
      summary: Adjuntar un bloque a un asistente
      description: >-
        Falla si el bloque es de otra company, o si dejaria al asistente con dos
        bloques de identidad del mismo tipo.
      operationId: PublicAssistantsController_attachBlock
      parameters:
        - name: id
          required: true
          in: path
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PublicBlockRefDto'
      responses:
        '201':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PublicAssistantEnvelopeDto'
      security:
        - PAT: []
components:
  schemas:
    PublicBlockRefDto:
      type: object
      properties:
        block_id:
          type: string
          description: ObjectId del bloque.
        pinned_version_id:
          type: string
          description: >-
            ObjectId de una version concreta. Sin este campo el asistente sigue
            la version vigente del bloque.
        order:
          type: number
          default: 0
          minimum: 0
          description: Posicion del bloque en el prompt.
      required:
        - block_id
    PublicAssistantEnvelopeDto:
      type: object
      properties:
        assistant:
          $ref: '#/components/schemas/PublicAssistantDto'
      required:
        - assistant
    PublicAssistantDto:
      type: object
      properties:
        id:
          type: string
        name:
          type: string
        description:
          type: string
        avatar_url:
          type: string
        model:
          type: string
        voice_response_enabled:
          type: boolean
          description: Indica si la respuesta de voz está habilitada.
        created_at:
          type: string
      required:
        - id
        - name
        - model
        - voice_response_enabled
  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`.

````