> ## 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/blocks/response-format

> Create a response format block with its content as plain text.

How the assistant writes: message length, emoji usage, and formatting rules. Separate from what it says, so you can change the voice without touching the content.

The block is created in the project catalogue and is **not attached to anything**. Wire it into an assistant with [`POST /v1/assistants/{id}/blocks`](/dev/endpoints/assistants-block-attach) afterwards.

<Note>
  **Identity block: one per assistant.** A second `response_format` on the same assistant fails with `ASSISTANT_DUPLICATE_IDENTITY_BLOCK`.
</Note>

## Endpoint

```
POST https://api.keebai.com/v1/blocks/response-format
```

## Required scope

`assistants:write`

## Headers

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

## Body

| Field     | Type     | Required | Description                                                                   |
| --------- | -------- | -------- | ----------------------------------------------------------------------------- |
| `name`    | `string` | Yes      | Up to 150 characters. What the block shows as in the portal.                  |
| `content` | `string` | No       | The block's text, up to 100,000 characters. Omit it to create an empty block. |

`type` and `family` are not accepted: the type is the endpoint you called, and `family` is derived from it (`identity` for this one).

## Example request

<CodeGroup>
  ```bash curl theme={null}
  curl -X POST https://api.keebai.com/v1/blocks/response-format \
    -H "Authorization: Bearer kbai_pk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
    -H "Content-Type: application/json" \
    -d '{
      "name": "Formato de respuesta",
      "content": "- Máximo tres líneas por mensaje.\n- Un emoji por mensaje como mucho.\n- Nunca usar listas con viñetas en WhatsApp.\n- Los precios van con separador de miles."
    }'
  ```

  ```js JavaScript theme={null}
  const resp = await fetch("https://api.keebai.com/v1/blocks/response-format", {
    method: "POST",
    headers: {
      Authorization: `Bearer ${process.env.KEEBAI_API_TOKEN}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      name: "Formato de respuesta",
      content: "- Máximo tres líneas por mensaje.\n- Un emoji por mensaje como mucho.\n- Nunca usar listas con viñetas en WhatsApp.\n- Los precios van con separador de miles.",
    }),
  });

  const { block } = await resp.json();

  // Then wire it into an assistant.
  await fetch("https://api.keebai.com/v1/assistants/6650a1b2c3d4e5f6a7b8c9d0/blocks", {
    method: "POST",
    headers: {
      Authorization: `Bearer ${process.env.KEEBAI_API_TOKEN}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({ block_id: block._id }),
  });
  ```

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

  resp = requests.post(
      "https://api.keebai.com/v1/blocks/response-format",
      headers={"Authorization": f"Bearer {os.environ['KEEBAI_API_TOKEN']}"},
      json={"name": "Formato de respuesta", "content": "- Máximo tres líneas por mensaje.\n- Un emoji por mensaje como mucho."},
      timeout=10,
  )
  resp.raise_for_status()
  block = resp.json()["block"]
  ```
</CodeGroup>

## Response

### 201 Created

```json theme={null}
{
  "block": {
    "_id": "6650bbbb2222cccc3333dddd",
    "type": "response_format",
    "family": "identity",
    "name": "Formato de respuesta",
    "current_version_id": "6650ffff4444aaaa5555bbbb",
    "is_archived": false,
    "content_writable": true,
    "created_at": "2026-07-26T21:38:22.104Z",
    "updated_at": "2026-07-26T21:38:22.104Z"
  }
}
```

### 400 Bad Request

Missing `name`, `content` over 100,000 characters, or a property the endpoint does not accept.

### 401 Unauthorized

Missing, invalid, revoked, or expired token.

### 403 Forbidden

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

### 502 Bad Gateway

The assistant service is unreachable.

## Operational notes

* Channel-specific rules belong here. The same assistant answering on WhatsApp and on web chat reads the same formatting block, so say which rule applies where.
* **Creating a block also creates its first version.** The response already carries a `current_version_id`, even when you omit `content` — the block starts with one empty version rather than none.
* **Creation is not idempotent.** Nothing enforces unique names, so a retry after a timeout leaves you with two blocks. Check [the catalogue](/dev/endpoints/blocks-list) filtered by `type` before retrying.
* **Content is plain text with three markdown conventions**: `-` for bullets, `1.` for numbered items, `#` for headings. Everything else is a paragraph. [More on how content is stored](/dev/assistants/overview#content-is-text).
* **The block belongs to the token's project**, and a token on another project can neither see it nor read it by id.


## OpenAPI

````yaml POST /v1/blocks/response-format
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/response-format:
    post:
      tags:
        - blocks
      summary: Crear un bloque de formato de respuesta
      description: >-
        Largo, uso de emojis y reglas de formato de los mensajes. Bloque de
        identidad, uno por asistente.
      operationId: PublicBlocksController_createResponseFormat
      parameters: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PublicBlockCreateDto'
      responses:
        '201':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PublicBlockEnvelopeDto'
      security:
        - PAT: []
components:
  schemas:
    PublicBlockCreateDto:
      type: object
      properties:
        name:
          type: string
          maxLength: 150
          description: Nombre con el que el bloque aparece en el portal.
          example: Tono cercano
        content:
          type: string
          maxLength: 100000
          description: >-
            Contenido inicial en texto. Se reconocen listas con '-' y con '1.',
            y encabezados con '#'. Sin este campo el bloque nace vacio.
      required:
        - name
    PublicBlockEnvelopeDto:
      type: object
      properties:
        block:
          $ref: '#/components/schemas/PublicBlockDto'
      required:
        - block
    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`.

````