---
title: "Referencia de la API de contactos"
description: "Busca, lee y actualiza contactos de Chatfuel: atributos, nombres, notas, responsables y etapas de venta, segmentos, importación y exportación CSV y eventos."
canonical_url: https://chatfuel.com/es/docs/public-api/contacts
markdown_url: https://chatfuel.com/es/docs/public-api/contacts.md
last_updated: 2026-10-06
lang: es
site: https://chatfuel.com/docs
llms_txt: https://chatfuel.com/llms.txt
---

# Referencia de la API de contactos

Busca, lee y actualiza contactos de Chatfuel: atributos, nombres, notas, responsables y etapas de venta, segmentos, importación y exportación CSV y eventos.

Un contacto es una persona que habló con el bot en WhatsApp, Instagram, Facebook, TikTok o el widget del sitio web. Con la Public API puedes buscar contactos con segmentos, leer sus atributos, cambiar nombres, atributos y notas, asignarlos a compañeros de equipo o a Fuely AI, moverlos entre etapas de venta e importarlos o exportarlos como CSV. Leer contactos funciona para usuarios virtuales **Agent**; editar los datos de un contacto requiere **Editor**.

A los contactos se accede a través de `bot(id:)`. El ID de un contacto también es el ID de su conversación, como se describe en [mensajería](https://chatfuel.com/es/docs/public-api/messaging).

## Cómo buscar y leer contactos [#cómo-buscar-y-leer-contactos]

```graphql
type Bot {
  # Agent. One contact by ID.
  contact(id: ContactID!): Contact!
  # Agent. Paginated search, up to 500 per page, optionally filtered by a segment and sorted by an attribute.
  contactsConnection(
    platforms: [Platform!]!          # whatsapp, instagram, facebook, tiktok, widget
    first: Int!
    before: ContactSearchCursor
    after: ContactSearchCursor
    segment: SegmentInput
    orderBy: ContactSearchOrderByInput   # { orderBy: <attribute name>, direction: Asc | Desc }
  ): ContactConnection!
  # Agent. Number of contacts matching the platforms and segment.
  contactsCount(platforms: [Platform!]!, segment: SegmentInput): Int!
  contactsTotalCount(platforms: [Platform!]!, segment: SegmentInput): Int!
}
```

`Contact` es una interfaz; los contactos de WhatsApp son `WhatsappContact`, con un campo `phone` adicional, y hay tipos similares para los demás canales. Todo contacto tiene:

```graphql
query Contact($botID: BotID!, $contactID: ContactID!) {
  bot(id: $botID) {
    contact(id: $contactID) {
      id
      name
      note
      updatedAt
      salesStageV2              # New, Sorting, Ready, WorkingOn, Won, Lost
      lastConversationMessageTime
      unreadMessagesCount
      unhandledSwitchToHuman    # handed to a human and not opened yet
      assignee {
        ... on PublicUserAccount { id name accountType }
        ... on FuelyAIAssignee { __typename }
      }
      attributes(names: ["email", "city"]) {
        attr { name type }
        value {
          ... on BotAttributeValueString { stringValue }
          ... on BotAttributeValueDouble { doubleValue }
          ... on BotAttributeValueBoolean { booleanValue }
          ... on BotAttributeValueDatetime { datetimeValue }
        }
      }
      ... on WhatsappContact { phone }
    }
  }
}
```

## Cómo filtrar contactos con segmentos [#cómo-filtrar-contactos-con-segmentos]

Un segmento es un conjunto de filtros unidos con `AND` u `OR`. Los IDs de segmentos y filtros son UUID que tú generas; también puedes llamar a `segmentNew` para obtener un segmento vacío con un ID:

```graphql
query Leads($botID: BotID!) {
  bot(id: $botID) {
    contactsConnection(
      platforms: [whatsapp]
      first: 100
      segment: {
        id: "2b0c6a0e-6f0a-4a39-9d63-0b1f0d4f7a10"
        resultOperator: AND
        filters: [{
          id: "8f6d2a4e-1c3b-4f5a-9e7d-2a1b3c4d5e6f"
          byAttribute: { name: "city", defaultStrategy: { operator: IS, comparableValues: ["Lisbon"] } }
        }]
      }
    ) {
      edges { node { id name } }
      pageInfo { hasNextPage endCursor }
    }
  }
}
```

Los filtros por atributo admiten los operadores `IS`, `IS_NOT`, `STARTS_WITH`, `CONTAINS`, `LT`, `GT`, `IS_EMPTY` e `IS_NOT_EMPTY`; los atributos de fecha usan `dateStrategy`. `bot.botAttributes(...)` lista los atributos del sistema y personalizados de un bot, con sus tipos de datos (**Agent**).

## Cómo actualizar un contacto [#cómo-actualizar-un-contacto]

```graphql
type Mutation {
  # Editor. Errors: ContactDoesNotExist, ContactNameTooLong, ContactNameRequired
  contactUpdateName(id: ContactID!, name: String!): Contact!
  # Editor. Creates or updates a custom attribute. System attributes can't be changed (SystemAttributeUpdateNotAllowed).
  contactAttributeUpdate(id: ContactID!, attrName: AttributeName!, attrValue: String!): Contact!
  # Editor. Deletes a custom attribute value from the contact.
  contactAttributeDelete(id: ContactID!, attrName: AttributeName!): Contact!
  # Editor. A free-text note shown on the contact card and in bookings. Errors: ContactNoteTooLong
  contactSetNote(id: ContactID!, note: String): Contact!
  # Agent. The person must have access to the bot's contacts (AssigneeHasNoAccess).
  contactSetAssignee(id: ContactID!, assigneeID: UserAccountID!): Contact!
  # Agent. Hands the contact to Fuely AI.
  contactSetFuelyAIAssignee(id: ContactID!): Contact!
  # Agent.
  contactRemoveAssignee(id: ContactID!): Contact!
  # Agent. Moves the contact on the Leads board.
  contactSetSalesStage(id: ContactID!, salesStageV2: SalesStageV2!): Contact!
  # Editor. Creates a WhatsApp contact by phone number for a calendar booking (source: CalendarBooking).
  whatsappContactCreateV2(botID: BotID!, data: WhatsappContactCreateInput!): Contact!
}
```

Un usuario virtual puede asignarse un contacto a sí mismo: pasa su propio `currentUser.id` como `assigneeID`.

Los valores predeterminados de los atributos del bot se aplican a todo contacto que no tenga un valor propio (**Editor**):

```graphql
type Mutation {
  botAttributeCreateDefaultVal(botID: BotID!, attributeName: AttributeName!, defaultValue: String!): Bot!
  botAttributeUpdateDefaultVal(botID: BotID!, attributeName: AttributeName!, defaultValue: String!): Bot!
  botAttributeDeleteDefaultVal(botID: BotID!, attributeName: AttributeName!): Bot!
}
```

## Cómo leer negocios por etapa de venta [#cómo-leer-negocios-por-etapa-de-venta]

El tablero de Leads agrupa los contactos por etapa de venta. Ambas consultas funcionan para **Agent**:

```graphql
type Bot {
  # Contacts in one stage, filtered by assignee (Any, Unassigned, FuelyAI or a specific AssigneeID).
  contactDealsConnection(
    first: Int!
    before: ContactSearchCursor
    after: ContactSearchCursor
    assigneeFilter: ContactAssigneeFilter!
    salesStageV2Filter: SalesStageV2!
  ): ContactConnection!
  # Number of contacts in each stage, optionally limited by the time of the last stage change.
  contactDealsByStages(filter: DealsByStagesFilter!): TotalsByStages!
}
```

## Cómo exportar e importar contactos como CSV [#cómo-exportar-e-importar-contactos-como-csv]

Las exportaciones e importaciones se ejecutan en segundo plano e informan su progreso mediante una [tarea o una suscripción](https://chatfuel.com/es/docs/public-api/files-and-tasks).

```graphql
type Mutation {
  # Agent. Export by segment; pass an empty attributes list to export all attributes.
  # Errors: CSVContactExportAlreadyInProgress
  csvContactExportStartBySegment(botID: BotID!, platforms: [Platform!]!, segment: SegmentInput, attributes: [AttributeName!]!): Task!
  # Agent. Export a list of contacts. Errors: CSVContactExportInvalidContactIDsCount
  csvContactExportStartByIDsList(botID: BotID!, contactIDs: [ContactID!]!, attributes: [AttributeName!]!): Task!
  # Agent. Cancels an export; the task status changes to cancelled shortly after.
  csvContactExportCancel(botID: BotID!, id: String!): Bot!

  # Editor. 1) upload the CSV file, 2) create the import, 3) map columns, 4) start it.
  csvContactImportCreate(botID: BotID!, fileID: FileID!, platform: Platform!, locale: DashboardLocale!): CSVContactImport!
  csvContactImportUpdateFile(botID: BotID!, id: CSVContactImportID!, fileID: FileID!): CSVContactImport!
  csvContactImportUpdateColumns(botID: BotID!, id: CSVContactImportID!, request: CSVContactImportColumnsUpdate!): CSVContactImport!
  # Errors: ContactScopeNotConnected if the channel, for example the WhatsApp number, is not connected.
  csvContactImportStart(botID: BotID!, id: CSVContactImportID!): CSVContactImport!
}
```

Cuando una tarea de exportación llega al estado `Finished`, su `data` es un `CSVContactsExport` cuyo `file { url }` es el CSV que debes descargar. `bot.lastActiveCSVContactsExportTask` (**Agent**) devuelve una exportación en curso, y `bot.latestCSVContactsImport(platform:)` (**Editor**), la última importación con sus contadores y errores.

## Suscripciones de contactos [#suscripciones-de-contactos]

```graphql
type Subscription {
  # Agent. Any change of one contact.
  contactUpdated(botID: BotID!, contactID: ContactID!): Contact
  # Agent. Changes on the Leads board for the given assignee filter.
  contactsDealUpdates(botID: BotID!, assigneeFilter: ContactAssigneeFilter!): ContactsDealUpdate
  contactsDealsPageIndicatorUpdates(botID: BotID!): DealsPageIndicatorUpdate
  # Editor. Progress of a CSV import.
  csvContactImportUpdated(botID: BotID!, id: CSVContactImportID!): CSVContactImport!
}
```

## Problemas comunes [#problemas-comunes]

### "NotEnoughPermissions" cuando un Agent edita un contacto [#notenoughpermissions-cuando-un-agent-edita-un-contacto]

Los Agents pueden asignar contactos y cambiar etapas de venta, pero cambiar nombres, atributos y notas requiere un Editor. Si un Editor también recibe este error, puede que la configuración de roles del bot lo limite a los contactos asignados a él, como se describe en [equipo y roles](https://chatfuel.com/es/docs/public-api/team-and-roles).

### "SystemAttributeUpdateNotAllowed" [#systemattributeupdatenotallowed]

Chatfuel define los atributos del sistema, como el número de teléfono o los datos de perfil del canal. Guarda tus propios datos en atributos personalizados.

### "ContactDoesNotExist" [#contactdoesnotexist]

El ID del contacto es incorrecto o pertenece a otro bot. Los IDs de contacto son específicos de cada bot; léelos de `contactsConnection` del mismo bot.
