> ## 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/crm/tickets

> List tickets with filters by pipeline, stage, owner, tag, channel, and creation date.

Returns a paginated list of tickets. Results cover the whole **company**, not just the project your token belongs to — see [Tenancy is implicit](/dev/crm/overview#tenancy-is-implicit).

All filters combine with AND. The comma-separated parameters (`stage_ids`, `tag_ids`, `categories`, `channel_ids`) match any of the listed values.

## Endpoint

```
GET https://api.keebai.com/v1/crm/tickets
```

## Required scope

`crm:tickets:read`

## Headers

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

## Query parameters

| Field          | Type      | Required | Description                                                                |
| -------------- | --------- | -------- | -------------------------------------------------------------------------- |
| `keyword`      | `string`  | No       | Free-text match over the ticket.                                           |
| `pipeline_id`  | `string`  | No       | Restrict to one pipeline.                                                  |
| `stage_ids`    | `string`  | No       | Comma-separated stage `ObjectId`s.                                         |
| `tag_ids`      | `string`  | No       | Comma-separated tag `ObjectId`s.                                           |
| `chat_user_id` | `string`  | No       | Restrict to one contact.                                                   |
| `assigned_to`  | `string`  | No       | Restrict to one owner.                                                     |
| `categories`   | `string`  | No       | Comma-separated category names.                                            |
| `channel_ids`  | `string`  | No       | Comma-separated channel `ObjectId`s.                                       |
| `completed`    | `string`  | No       | `true` returns only closed tickets, `false` only open ones. Omit for both. |
| `date_from`    | `string`  | No       | Created on or after this date (`YYYY-MM-DD`).                              |
| `date_to`      | `string`  | No       | Created on or before this date (`YYYY-MM-DD`).                             |
| `limit`        | `integer` | No       | Page size, `1`–`200`. Defaults to 50.                                      |
| `offset`       | `integer` | No       | Records to skip. Defaults to 0.                                            |

## Example request

<CodeGroup>
  ```bash curl theme={null}
  curl -G https://api.keebai.com/v1/crm/tickets \
    -H "Authorization: Bearer kbai_pk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
    --data-urlencode "completed=false" \
    --data-urlencode "stage_ids=65b1c2d3e4f5a6b7c8d9e0f1,66c1d2e3f4a5b6c7d8e9f0a1" \
    --data-urlencode "limit=50"
  ```

  ```js JavaScript theme={null}
  const params = new URLSearchParams({
    completed: "false",
    stage_ids: openStages.join(","),
    limit: "50",
  });

  const response = await fetch(
    `https://api.keebai.com/v1/crm/tickets?${params}`,
    { headers: { Authorization: `Bearer ${process.env.KEEBAI_API_TOKEN}` } },
  );
  const { data, total } = await response.json();
  ```

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

  resp = requests.get(
      "https://api.keebai.com/v1/crm/tickets",
      headers={"Authorization": f"Bearer {os.environ['KEEBAI_API_TOKEN']}"},
      params={
          "completed": "false",
          "stage_ids": ",".join(open_stages),
          "limit": 50,
      },
      timeout=10,
  )
  resp.raise_for_status()
  tickets = resp.json()["data"]
  ```
</CodeGroup>

## Response

### 200 OK

```json theme={null}
{
  "data": [
    {
      "_id": "65f4b5c6d7e8f9a0b1c2d3e4",
      "chat_user": "66c1d2e3f4a5b6c7d8e9f0a1",
      "chat_user_name": "Juan Pérez",
      "chat_user_channel": "whatsapp",
      "stage": "67d1e2f3a4b5c6d7e8f9a0b1",
      "is_closed": false,
      "priority": "medium",
      "category": "soporte",
      "assigned_to": "68e1f2a3b4c5d6e7f8a9b0c1",
      "custom_fields": {},
      "amount": 150000,
      "amount_currency": "CLP",
      "amount_status": "estimated",
      "created_at": "2026-05-02T14:31:07.221Z",
      "updated_at": "2026-05-02T15:02:44.010Z"
    }
  ],
  "total": 1,
  "limit": 50,
  "offset": 0
}
```

### 400 Bad Request

`limit` above 200, negative `offset`, or an unknown query parameter.

### 401 Unauthorized

Missing, invalid, revoked, or expired token.

### 403 Forbidden

The token does not have the `crm:tickets:read` scope.

## Operational notes

* **`completed` is a string, not a boolean.** Send the literal `"true"` or `"false"`; omitting it returns open and closed tickets together.
* **Stage and tag ids are opaque.** There is no public endpoint for listing pipelines and stages yet — read those ids from the portal, or capture them from [outbound webhook](/dev/webhooks/overview) payloads.
* To poll for changes, filter by `date_from` on a rolling window rather than paging the entire company on every run.


## OpenAPI

````yaml GET /v1/crm/tickets
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/crm/tickets:
    get:
      tags:
        - crm-tickets
      summary: Listar tickets
      description: >-
        Devuelve los tickets de la company del token. El listado no filtra por
        project.
      operationId: PublicTicketsController_list
      parameters:
        - name: keyword
          required: false
          in: query
          description: Búsqueda libre sobre el ticket
          schema:
            type: string
        - name: pipeline_id
          required: false
          in: query
          description: Filtrar por pipeline
          schema:
            type: string
        - name: stage_ids
          required: false
          in: query
          description: Ids de etapa separados por coma
          schema:
            type: string
        - name: tag_ids
          required: false
          in: query
          description: Ids de tag separados por coma
          schema:
            type: string
        - name: chat_user_id
          required: false
          in: query
          description: Filtrar por chat user (contacto)
          schema:
            type: string
        - name: assigned_to
          required: false
          in: query
          description: Filtrar por usuario asignado
          schema:
            type: string
        - name: categories
          required: false
          in: query
          description: Categorías separadas por coma
          schema:
            type: string
        - name: channel_ids
          required: false
          in: query
          description: Ids de canal separados por coma
          schema:
            type: string
        - name: completed
          required: false
          in: query
          description: '''true'' devuelve sólo cerrados, ''false'' sólo abiertos'
          schema:
            type: string
        - name: date_from
          required: false
          in: query
          description: Fecha de creación desde (YYYY-MM-DD)
          schema:
            type: string
        - name: date_to
          required: false
          in: query
          description: Fecha de creación hasta (YYYY-MM-DD)
          schema:
            type: string
        - 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
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PublicTicketListResponseDto'
      security:
        - PAT: []
components:
  schemas:
    PublicTicketListResponseDto:
      type: object
      properties:
        data:
          type: array
          items:
            $ref: '#/components/schemas/PublicTicketResponseDto'
        total:
          type: number
        limit:
          type: number
        offset:
          type: number
      required:
        - data
        - total
        - limit
        - offset
    PublicTicketResponseDto:
      type: object
      properties:
        _id:
          type: string
          description: ObjectId del ticket
        chat_user:
          type: string
          description: ObjectId del chat user (contacto)
        chat_user_name:
          type: string
        chat_user_avatar:
          type: string
        chat_user_channel:
          type: string
          description: Canal de origen (whatsapp, instagram…)
        chat_user_channel_id:
          type: string
        stage:
          description: Etapa actual del pipeline. Ausente si el ticket no tiene una.
          allOf:
            - $ref: '#/components/schemas/PublicTicketStageDto'
        is_closed:
          type: boolean
        resolution:
          type: string
          enum:
            - won
            - lost
        priority:
          type: string
          enum:
            - low
            - medium
            - high
            - urgent
        category:
          type: string
        assigned_to:
          $ref: '#/components/schemas/PublicTicketAssigneeDto'
        tags:
          type: array
          items:
            $ref: '#/components/schemas/PublicTicketTagDto'
        custom_fields:
          type: object
        amount:
          type: number
        amount_currency:
          type: string
          description: Moneda ISO 4217
        amount_status:
          type: string
          enum:
            - estimated
            - confirmed
        conversation_summary:
          $ref: '#/components/schemas/PublicConversationSummaryDto'
        ai_feedback_status:
          type: string
          description: 'Feedback de la IA: resolved | unresolved'
        appointment_ids:
          description: Citas de scheduling vinculadas al ticket
          type: array
          items:
            type: string
        last_message:
          description: Último mensaje del contacto. Sólo presente en el listado.
          allOf:
            - $ref: '#/components/schemas/PublicTicketLastMessageDto'
        closed_at:
          type: string
          format: date-time
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
      required:
        - _id
        - chat_user
        - is_closed
        - priority
        - tags
        - custom_fields
        - created_at
        - updated_at
    PublicTicketStageDto:
      type: object
      properties:
        stage_id:
          type: string
          description: Etapa de destino dentro del pipeline
        prioridad:
          type: string
          description: Prioridad reportada al mover la etapa
        contexto:
          type: string
          description: Contexto del movimiento
        problema:
          type: string
          description: Problema detectado
        recomendaciones:
          type: string
          description: Recomendaciones para el operador
      required:
        - stage_id
    PublicTicketAssigneeDto:
      type: object
      properties:
        id:
          type: string
          description: ObjectId del usuario
        full_name:
          type: string
        email:
          type: string
      required:
        - id
    PublicTicketTagDto:
      type: object
      properties:
        id:
          type: string
          description: ObjectId del tag
        name:
          type: string
        color:
          type: string
          description: 'Color hex, ej. #1890ff'
      required:
        - id
        - name
    PublicConversationSummaryDto:
      type: object
      properties:
        motivo:
          type: string
        estado:
          type: string
        proximos_pasos:
          type: string
        is_final:
          type: boolean
    PublicTicketLastMessageDto:
      type: object
      properties:
        id:
          type: string
        content:
          type: string
        role:
          type: string
        direction:
          type: string
          description: inbound | outbound
        created_at:
          type: string
          format: date-time
      required:
        - id
  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`.

````