# Contatos

## Listar contatos

`GET /v1/c/{slug}/contacts` · Escopos: `contacts:read`

Os mais ativos primeiro. `q` busca por nome ou telefone; `tag` filtra por etiqueta; `before` (o `lastActivityAt` do último da página) traz a próxima página.

### Parâmetros do endereço

| Campo | Detalhes |
|---|---|
| `slug` | O identificador da empresa no DoneTalk (o mesmo da chave). |

### Parâmetros de consulta

| Campo | Tipo | Obrigatório | Detalhes |
|---|---|---|---|
| `q` | string | não | até 200 caracteres |
| `limit` | integer | não | até 100; mínimo 1; default `50` |
| `before` | string (date-time) | não |  |
| `tag` | string (uuid) | não |  |

### Exemplo de pedido

```bash
curl -X GET "https://api.donetalk.com/v1/c/demo/contacts" \
  -H "Authorization: Bearer $DONETALK_KEY"
```

### Resposta 200

```json
{
  "contacts": [
    {
      "id": "01a0d05a-3ee3-75bd-9db5-dc9856f079c8",
      "displayName": "Ana Souza",
      "address": "5548999990001",
      "channelKind": "whatsapp",
      "source": "api",
      "externalRef": "erp-88213",
      "fields": {
        "cpf": "529.982.247-25",
        "plano": "anual"
      },
      "isBlocked": false,
      "lastActivityAt": "2026-10-22T18:40:02.000Z",
      "createdAt": "2026-09-23T22:19:30.396Z",
      "tags": [
        {
          "id": "01a12150-3610-7c00-b680-188c2b4c7313",
          "name": {
            "pt-BR": "VIP",
            "en": "VIP",
            "es": "VIP"
          },
          "color": "#92400e"
        }
      ]
    }
  ]
}
```

### Erros possíveis

- `401` `unauthorized`
- `403` `insufficient_scope`
- `422` `validation_failed`
- `429` `rate_limited`

## Criar um contato

`POST /v1/c/{slug}/contacts` · Escopos: `contacts:write`

Para criar ou atualizar vários de uma vez (ou um que talvez já exista), use `POST /contacts/import`.

### Parâmetros do endereço

| Campo | Detalhes |
|---|---|
| `slug` | O identificador da empresa no DoneTalk (o mesmo da chave). |

### Corpo do pedido

| Campo | Tipo | Obrigatório | Detalhes |
|---|---|---|---|
| `displayName` | string | sim | até 200 caracteres |
| `phone` | string | sim |  |
| `locale` | um de `pt-BR`, `es`, `en` | não |  |
| `fields` | object | não |  |
| `externalRef` | string | não | até 200 caracteres |

### Exemplo de pedido

```bash
curl -X POST "https://api.donetalk.com/v1/c/demo/contacts" \
  -H "Authorization: Bearer $DONETALK_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "displayName": "Ana Souza",
  "phone": "+5548999990001",
  "externalRef": "erp-88213",
  "fields": {
    "cpf": "529.982.247-25"
  }
}'
```

### Resposta 201

```json
{
  "contact": {
    "id": "01a0d05a-3ee3-75bd-9db5-dc9856f079c8",
    "displayName": "Ana Souza",
    "address": "5548999990001"
  }
}
```

### Erros possíveis

- `401` `unauthorized`
- `403` `insufficient_scope`
- `409` `contact_exists`
- `422` `validation_failed`
- `429` `rate_limited`

## Criar ou atualizar contatos (até 1.000)

`POST /v1/c/{slug}/contacts/import` · Escopos: `contacts:write`

Pelo telefone: quem já existe é atualizado (nome, campos, etiquetas), quem não existe é criado. Cada linha volta com o id do contato. Uma linha com problema não derruba as outras.

### Parâmetros do endereço

| Campo | Detalhes |
|---|---|
| `slug` | O identificador da empresa no DoneTalk (o mesmo da chave). |

### Corpo do pedido

| Campo | Tipo | Obrigatório | Detalhes |
|---|---|---|---|
| `rows` | lista de objeto | sim | até 1000 |
| `rows[].phone` | string | sim | até 40 caracteres |
| `rows[].name` | string | não | até 200 caracteres |
| `rows[].fields` | object | não |  |
| `rows[].tags` | lista de string | não | até 20 |
| `rows[].externalRef` | string | não | até 200 caracteres |
| `rows[].marketingOptIn` | boolean | não |  |

### Exemplo de pedido

```bash
curl -X POST "https://api.donetalk.com/v1/c/demo/contacts/import" \
  -H "Authorization: Bearer $DONETALK_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "rows": [
    {
      "phone": "+5548999990001",
      "name": "Ana Souza",
      "tags": [
        "VIP"
      ],
      "externalRef": "erp-88213"
    },
    {
      "phone": "48 99999-0002",
      "name": "Bruno Lima",
      "fields": {
        "plano": "mensal"
      },
      "marketingOptIn": true
    }
  ]
}'
```

### Resposta 200

```json
{
  "created": 1,
  "updated": 1,
  "errors": [
    {
      "row": 2,
      "reason": "invalid_phone"
    }
  ],
  "contacts": [
    {
      "row": 0,
      "contactId": "01a0d05a-3ee3-75bd-9db5-dc9856f079c8",
      "created": false
    },
    {
      "row": 1,
      "contactId": "01a0d05a-3ee3-75bd-9db5-dc9856f079c9",
      "created": true
    }
  ]
}
```

### Erros possíveis

- `401` `unauthorized`
- `403` `insufficient_scope`
- `422` `validation_failed`
- `429` `rate_limited`

## Ver um contato

`GET /v1/c/{slug}/contacts/{id}` · Escopos: `contacts:read`

O contato com seus campos, números, consentimentos, últimos atendimentos e etiquetas, e as definições dos campos da empresa.

### Parâmetros do endereço

| Campo | Detalhes |
|---|---|
| `slug` | O identificador da empresa no DoneTalk (o mesmo da chave). |
| `id` | O id do registro. |

### Exemplo de pedido

```bash
curl -X GET "https://api.donetalk.com/v1/c/demo/contacts/:id" \
  -H "Authorization: Bearer $DONETALK_KEY"
```

### Resposta 200

```json
{
  "contact": {
    "id": "01a0d05a-3ee3-75bd-9db5-dc9856f079c8",
    "displayName": "Ana Souza",
    "address": "5548999990001",
    "channelKind": "whatsapp",
    "source": "api",
    "externalRef": "erp-88213",
    "fields": {
      "cpf": "529.982.247-25",
      "plano": "anual"
    },
    "isBlocked": false,
    "lastActivityAt": "2026-10-22T18:40:02.000Z",
    "createdAt": "2026-09-23T22:19:30.396Z",
    "firstName": "Ana",
    "lastName": "Souza",
    "locale": "pt-BR",
    "timezone": null,
    "blockedReason": null
  },
  "identities": [
    {
      "id": "01a0d05a-3ee3-75bd-9db5-dc9856f079c9",
      "channel_kind": "whatsapp",
      "address": "5548999990001",
      "external_id": null,
      "provider_display_name": "Ana",
      "is_primary": true,
      "last_seen_at": "2026-10-22T18:40:02.000Z"
    }
  ],
  "consents": [
    {
      "purpose": "marketing",
      "channel_kind": "whatsapp",
      "status": "opted_in",
      "source": "api",
      "occurred_at": "2026-10-01T10:00:00.000Z"
    }
  ],
  "conversations": [
    {
      "id": "01a3c0de-7a11-7b22-8c33-9d44e55f6677",
      "status": "closed",
      "source_kind": "campaign",
      "imported_from": null,
      "created_at": "2026-10-24T12:00:04.000Z",
      "closed_at": "2026-10-24T12:20:41.000Z",
      "channel_id": "01a0cccc-0000-7000-8000-000000000002",
      "outcome_code": "converted",
      "is_success": true
    }
  ],
  "tags": [
    {
      "id": "01a12150-3610-7c00-b680-188c2b4c7313",
      "name": {
        "pt-BR": "VIP",
        "en": "VIP",
        "es": "VIP"
      },
      "color": "#92400e"
    }
  ],
  "fieldDefinitions": [
    {
      "key": "cpf",
      "label": {
        "pt-BR": "CPF",
        "en": "CPF",
        "es": "CPF"
      },
      "type": "cpf",
      "options": null,
      "ai_extractable": true,
      "required": false,
      "sort": 1
    }
  ]
}
```

### Erros possíveis

- `401` `unauthorized`
- `403` `insufficient_scope`
- `404` `contact_not_found`
- `422` `validation_failed`
- `429` `rate_limited`

## Editar um contato

`PATCH /v1/c/{slug}/contacts/{id}` · Escopos: `contacts:write`

`fields` junta com os campos que o contato já tem; mande `null` num campo para apagá-lo.

### Parâmetros do endereço

| Campo | Detalhes |
|---|---|
| `slug` | O identificador da empresa no DoneTalk (o mesmo da chave). |
| `id` | O id do registro. |

### Corpo do pedido

| Campo | Tipo | Obrigatório | Detalhes |
|---|---|---|---|
| `displayName` | string | não | até 200 caracteres |
| `firstName` | string | não | até 100 caracteres; null |
| `lastName` | string | não | até 100 caracteres; null |
| `locale` | um de `pt-BR`, `es`, `en` | não | null |
| `externalRef` | string | não | até 200 caracteres; null |
| `fields` | object | não |  |
| `isBlocked` | boolean | não |  |
| `blockedReason` | string | não | até 200 caracteres; null |

### Exemplo de pedido

```bash
curl -X PATCH "https://api.donetalk.com/v1/c/demo/contacts/:id" \
  -H "Authorization: Bearer $DONETALK_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "fields": {
    "plano": "anual"
  },
  "externalRef": "erp-88213"
}'
```

### Resposta 200

```json
{
  "ok": true
}
```

### Erros possíveis

- `401` `unauthorized`
- `403` `insufficient_scope`
- `404` `contact_not_found`
- `422` `validation_failed`
- `429` `rate_limited`

## Registrar consentimento

`POST /v1/c/{slug}/contacts/{id}/consents` · Escopos: `contacts:write`

Opt-in ou opt-out por finalidade (atendimento, utilidade, marketing). Marketing com opt-out tira o contato das campanhas de marketing.

### Parâmetros do endereço

| Campo | Detalhes |
|---|---|
| `slug` | O identificador da empresa no DoneTalk (o mesmo da chave). |
| `id` | O id do registro. |

### Corpo do pedido

| Campo | Tipo | Obrigatório | Detalhes |
|---|---|---|---|
| `purpose` | um de `service`, `utility`, `marketing` | sim |  |
| `status` | um de `opted_in`, `opted_out` | sim |  |
| `source` | um de `form`, `import`, `api`, `message`, `keyword` | não | default `"form"` |
| `evidence` | object | não |  |

### Exemplo de pedido

```bash
curl -X POST "https://api.donetalk.com/v1/c/demo/contacts/:id/consents" \
  -H "Authorization: Bearer $DONETALK_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "purpose": "marketing",
  "status": "opted_in",
  "source": "api"
}'
```

### Resposta 201

```json
{
  "ok": true
}
```

### Erros possíveis

- `401` `unauthorized`
- `403` `insufficient_scope`
- `404` `contact_not_found`
- `422` `validation_failed`
- `429` `rate_limited`

## Pôr uma etiqueta

`PUT /v1/c/{slug}/contacts/{id}/tags/{tagId}` · Escopos: `contacts:write`

Pode iniciar os fluxos que começam quando essa etiqueta é colocada.

### Parâmetros do endereço

| Campo | Detalhes |
|---|---|
| `slug` | O identificador da empresa no DoneTalk (o mesmo da chave). |
| `id` | O id do registro. |
| `tagId` | O id da etiqueta. |

### Exemplo de pedido

```bash
curl -X PUT "https://api.donetalk.com/v1/c/demo/contacts/:id/tags/:tagId" \
  -H "Authorization: Bearer $DONETALK_KEY"
```

### Resposta 200

```json
{
  "ok": true
}
```

### Erros possíveis

- `401` `unauthorized`
- `403` `insufficient_scope`
- `422` `validation_failed`
- `429` `rate_limited`

## Tirar uma etiqueta

`DELETE /v1/c/{slug}/contacts/{id}/tags/{tagId}` · Escopos: `contacts:write`

### Parâmetros do endereço

| Campo | Detalhes |
|---|---|
| `slug` | O identificador da empresa no DoneTalk (o mesmo da chave). |
| `id` | O id do registro. |
| `tagId` | O id da etiqueta. |

### Exemplo de pedido

```bash
curl -X DELETE "https://api.donetalk.com/v1/c/demo/contacts/:id/tags/:tagId" \
  -H "Authorization: Bearer $DONETALK_KEY"
```

### Resposta 200

```json
{
  "ok": true
}
```

### Erros possíveis

- `401` `unauthorized`
- `403` `insufficient_scope`
- `422` `validation_failed`
- `429` `rate_limited`

## Fichas de contexto

`GET /v1/c/{slug}/contacts/{id}/context-cards` · Escopos: `contacts:read`

### Parâmetros do endereço

| Campo | Detalhes |
|---|---|
| `slug` | O identificador da empresa no DoneTalk (o mesmo da chave). |
| `id` | O id do registro. |

### Exemplo de pedido

```bash
curl -X GET "https://api.donetalk.com/v1/c/demo/contacts/:id/context-cards" \
  -H "Authorization: Bearer $DONETALK_KEY"
```

### Resposta 200

```json
{
  "cards": [
    {
      "key": "erp",
      "source": "ERP Captei",
      "title": "Cliente desde 2023",
      "status": "Plano anual",
      "tone": "success",
      "fields": [
        {
          "label": "Pedidos",
          "value": "14"
        }
      ],
      "link": {
        "url": "https://erp.captei.com.br/clientes/88213",
        "label": "Abrir no ERP"
      },
      "updatedAt": "2026-10-23T13:02:11.000Z"
    }
  ]
}
```

### Erros possíveis

- `401` `unauthorized`
- `403` `insufficient_scope`
- `422` `validation_failed`
- `429` `rate_limited`

## Mostrar uma ficha a quem atende

`PUT /v1/c/{slug}/contacts/{id}/context-cards/{key}` · Escopos: `contacts:write`

Uma ficha do seu sistema que aparece ao lado da conversa (plano, pedidos, saldo). A mesma `key` substitui a anterior.

### Parâmetros do endereço

| Campo | Detalhes |
|---|---|
| `slug` | O identificador da empresa no DoneTalk (o mesmo da chave). |
| `id` | O id do registro. |
| `key` | A chave (do campo ou da ficha). |

### Corpo do pedido

| Campo | Tipo | Obrigatório | Detalhes |
|---|---|---|---|
| `title` | string | sim | até 120 caracteres |
| `source` | string | não | até 60 caracteres |
| `status` | string | não | até 60 caracteres; null |
| `tone` | um de `neutral`, `success`, `warning`, `danger`, `info` | não | default `"neutral"` |
| `fields` | lista de objeto | não | até 12; default `[]` |
| `fields[].label` | string | sim | até 60 caracteres |
| `fields[].value` | string | sim | até 300 caracteres |
| `link` | objeto | não | null |
| `link.url` | string (uri) | sim | até 2000 caracteres |
| `link.label` | string | não | até 60 caracteres |

### Exemplo de pedido

```bash
curl -X PUT "https://api.donetalk.com/v1/c/demo/contacts/:id/context-cards/:key" \
  -H "Authorization: Bearer $DONETALK_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "title": "Cliente desde 2023",
  "source": "ERP Captei",
  "status": "Plano anual",
  "tone": "success",
  "fields": [
    {
      "label": "Pedidos",
      "value": "14"
    }
  ],
  "link": {
    "url": "https://erp.captei.com.br/clientes/88213",
    "label": "Abrir no ERP"
  }
}'
```

### Resposta 200

```json
{
  "card": {
    "key": "erp",
    "source": "ERP Captei",
    "title": "Cliente desde 2023",
    "status": "Plano anual",
    "tone": "success",
    "fields": [
      {
        "label": "Pedidos",
        "value": "14"
      }
    ],
    "link": {
      "url": "https://erp.captei.com.br/clientes/88213",
      "label": "Abrir no ERP"
    },
    "updatedAt": "2026-10-23T13:02:11.000Z"
  }
}
```

### Erros possíveis

- `401` `unauthorized`
- `403` `insufficient_scope`
- `422` `validation_failed`
- `429` `rate_limited`

## Tirar uma ficha

`DELETE /v1/c/{slug}/contacts/{id}/context-cards/{key}` · Escopos: `contacts:write`

### Parâmetros do endereço

| Campo | Detalhes |
|---|---|
| `slug` | O identificador da empresa no DoneTalk (o mesmo da chave). |
| `id` | O id do registro. |
| `key` | A chave (do campo ou da ficha). |

### Exemplo de pedido

```bash
curl -X DELETE "https://api.donetalk.com/v1/c/demo/contacts/:id/context-cards/:key" \
  -H "Authorization: Bearer $DONETALK_KEY"
```

### Resposta 200

```json
{
  "ok": true
}
```

### Erros possíveis

- `401` `unauthorized`
- `403` `insufficient_scope`
- `422` `validation_failed`
- `429` `rate_limited`

## Apagar os dados do contato (LGPD)

`POST /v1/c/{slug}/contacts/{id}/erase` · Escopos: `contacts:delete`

A pedido do titular: o contato e suas mensagens são anonimizados de vez. Não tem volta.

### Parâmetros do endereço

| Campo | Detalhes |
|---|---|
| `slug` | O identificador da empresa no DoneTalk (o mesmo da chave). |
| `id` | O id do registro. |

### Exemplo de pedido

```bash
curl -X POST "https://api.donetalk.com/v1/c/demo/contacts/:id/erase" \
  -H "Authorization: Bearer $DONETALK_KEY"
```

### Resposta 200

```json
{
  "ok": true
}
```

### Erros possíveis

- `401` `unauthorized`
- `403` `insufficient_scope`
- `404` `contact_not_found`
- `422` `validation_failed`
- `429` `rate_limited`

