# Campanhas

## Listar campanhas

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

As campanhas mais novas primeiro, com os números de cada uma. Filtre por `status`.

### 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 |
|---|---|---|---|
| `status` | string | não | até 40 caracteres |
| `limit` | integer | não | até 200; mínimo 1; default `200` |
| `cursor` | string | não | até 200 caracteres |

### Exemplo de pedido

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

### Resposta 200

```json
{
  "campaigns": [
    {
      "id": "01a2b3c4-5d6e-7f80-9a1b-2c3d4e5f6a7b",
      "name": "Reativação · outubro",
      "status": "draft",
      "channel": {
        "id": "01a0cccc-0000-7000-8000-000000000002",
        "name": "Captei"
      },
      "template": {
        "id": "01a0cad0-0000-7000-8000-000000000002",
        "name": "reativacao_cupom",
        "category": "marketing"
      },
      "variables": [
        {
          "slot": "body.1",
          "source": "first_name",
          "format": "none",
          "fallback": "tudo bem"
        },
        {
          "slot": "body.2",
          "source": "value.cupom",
          "format": "upper",
          "fallback": ""
        }
      ],
      "buttons": [
        {
          "index": 0,
          "action": "route"
        }
      ],
      "audience": {
        "kind": "contacts",
        "contactIds": [
          "01a0d05a-3ee3-75bd-9db5-dc9856f079c8",
          "01a0d05a-3ee3-75bd-9db5-dc9856f079c9"
        ]
      },
      "excludeOpen": true,
      "frequencyDays": 7,
      "startAt": "2026-10-24T12:00:00.000Z",
      "sendWindow": [
        {
          "day": 1,
          "from": "09:00",
          "to": "18:00"
        }
      ],
      "reply": {
        "kind": "team",
        "id": "01a0cb22-89c0-7e02-b96b-3f4731dde701",
        "goal": null
      },
      "successDays": 7,
      "stopRules": {
        "templatePaused": true,
        "qualityLow": true,
        "optoutRate": 0.03,
        "budget": true
      },
      "budgetMicros": null,
      "estimate": {
        "micros": 77824000,
        "currency": "BRL"
      },
      "audienceCount": 1240,
      "header": null,
      "approval": {
        "required": false,
        "requestedTo": null,
        "requestedAt": null,
        "approvedBy": null,
        "approvedAt": null,
        "rejectedReason": null
      },
      "createdBy": null,
      "createdByKind": "api",
      "startedAt": null,
      "paused": null,
      "completedAt": null,
      "createdAt": "2026-10-23T13:02:11.000Z",
      "updatedAt": "2026-10-23T13:02:11.000Z",
      "stats": {
        "audience": 1240,
        "queued": 0,
        "sending": 0,
        "sent": 1216,
        "delivered": 1198,
        "read": 874,
        "failed": 18,
        "skipped": 24,
        "replied": 141,
        "optedOut": 6,
        "successes": 37,
        "costMicros": 77824000,
        "followMicros": 1260000,
        "aiUsdMicros": 0
      }
    }
  ],
  "nextCursor": null
}
```

### Erros possíveis

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

## Criar uma campanha

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

Cria um rascunho. Nada é enviado até `submit`. O público pode ser um segmento, um filtro ou uma lista de contatos: por id (`contactIds`) ou por telefone (`people`), com valores próprios de cada pessoa para as variáveis `value.<chave>`. Cada telefone vira um contato, criado ou atualizado, o que pede também o escopo contacts:write.

### 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 |
|---|---|---|---|
| `name` | string | sim | até 120 caracteres |
| `channelId` | string (uuid) | não | null |
| `templateId` | string (uuid) | não | null |
| `variables` | lista de objeto | não | até 40 |
| `variables[].slot` | string | sim |  |
| `variables[].source` | um de `name`, `first_name`, `phone`, `fixed` · string | sim |  |
| `variables[].value` | string | não | até 500 caracteres |
| `variables[].format` | um de `none`, `title`, `upper`, `lower`, `first` | não | default `"none"` |
| `variables[].fallback` | string | não | até 200 caracteres; default `""` |
| `buttons` | lista de objeto | não | até 10 |
| `buttons[].index` | integer | sim | até 9 |
| `buttons[].action` | um de `route`, `optout`, `none` | sim |  |
| `audience` | objeto | não | null |
| `audience.kind` | um de `segment` | sim |  |
| `audience.segmentId` | string (uuid) | sim |  |
| `audience.conditions` | lista de objeto | sim | até 20 |
| `audience.conditions[].field` | string | sim | até 80 caracteres |
| `audience.conditions[].op` | um de `eq`, `neq`, `has`, `not_has`, `contains`, `empty`, `not_empty`, `gt`, `lt`, `none` | sim |  |
| `audience.conditions[].value` | string · number · boolean · um de `null` | não |  |
| `audience.contactIds` | lista de string (uuid) | não | até 20000; default `[]` |
| `audience.people` | lista de objeto | não | até 20000 |
| `audience.people[].phone` | string | sim | até 40 caracteres |
| `audience.people[].name` | string | não | até 200 caracteres |
| `audience.people[].fields` | object | não |  |
| `audience.people[].tags` | lista de string | não | até 20 |
| `audience.people[].values` | object | não |  |
| `audience.values` | object | não |  |
| `excludeOpen` | boolean | não |  |
| `frequencyDays` | integer | não | até 90; null |
| `startAt` | string (date-time) | não | null |
| `sendWindow` | lista de objeto | não | até 14 |
| `sendWindow[].day` | integer | sim | até 7; mínimo 1 |
| `sendWindow[].from` | string | sim |  |
| `sendWindow[].to` | string | sim |  |
| `reply` | objeto | não |  |
| `reply.kind` | um de `team`, `flow`, `assistant` | não | default `"team"` |
| `reply.id` | string (uuid) | não | default `null`; null |
| `reply.goal` | string | não | até 200 caracteres; default `null`; null |
| `successDays` | integer | não | até 60; mínimo 1 |
| `stopRules` | objeto | não |  |
| `stopRules.templatePaused` | boolean | não | default `true` |
| `stopRules.qualityLow` | boolean | não | default `true` |
| `stopRules.optoutRate` | number | não | até 0.5; mínimo 0.005; default `0.03`; null |
| `stopRules.budget` | boolean | não | default `true` |
| `budgetMicros` | integer | não | até 1000000000000000; null |

### Exemplo de pedido

```bash
curl -X POST "https://api.donetalk.com/v1/c/demo/campaigns" \
  -H "Authorization: Bearer $DONETALK_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "name": "Reativação · outubro",
  "channelId": "01a0cccc-0000-7000-8000-000000000002",
  "templateId": "01a0cad0-0000-7000-8000-000000000002",
  "variables": [
    {
      "slot": "body.1",
      "source": "first_name",
      "fallback": "tudo bem"
    },
    {
      "slot": "body.2",
      "source": "value.cupom",
      "format": "upper"
    }
  ],
  "buttons": [
    {
      "index": 0,
      "action": "route"
    }
  ],
  "audience": {
    "kind": "contacts",
    "people": [
      {
        "phone": "+5548999990001",
        "name": "Ana Souza",
        "values": {
          "cupom": "ana10"
        }
      },
      {
        "phone": "+5548999990002",
        "name": "Bruno Lima",
        "values": {
          "cupom": "bru15"
        }
      }
    ]
  },
  "reply": {
    "kind": "team",
    "id": "01a0cb22-89c0-7e02-b96b-3f4731dde701"
  },
  "startAt": "2026-10-24T12:00:00.000Z"
}'
```

### Resposta 201

```json
{
  "campaign": {
    "id": "01a2b3c4-5d6e-7f80-9a1b-2c3d4e5f6a7b",
    "name": "Reativação · outubro",
    "status": "draft",
    "channel": {
      "id": "01a0cccc-0000-7000-8000-000000000002",
      "name": "Captei"
    },
    "template": {
      "id": "01a0cad0-0000-7000-8000-000000000002",
      "name": "reativacao_cupom",
      "category": "marketing"
    },
    "variables": [
      {
        "slot": "body.1",
        "source": "first_name",
        "format": "none",
        "fallback": "tudo bem"
      },
      {
        "slot": "body.2",
        "source": "value.cupom",
        "format": "upper",
        "fallback": ""
      }
    ],
    "buttons": [
      {
        "index": 0,
        "action": "route"
      }
    ],
    "audience": {
      "kind": "contacts",
      "contactIds": [
        "01a0d05a-3ee3-75bd-9db5-dc9856f079c8",
        "01a0d05a-3ee3-75bd-9db5-dc9856f079c9"
      ]
    },
    "excludeOpen": true,
    "frequencyDays": 7,
    "startAt": "2026-10-24T12:00:00.000Z",
    "sendWindow": [
      {
        "day": 1,
        "from": "09:00",
        "to": "18:00"
      }
    ],
    "reply": {
      "kind": "team",
      "id": "01a0cb22-89c0-7e02-b96b-3f4731dde701",
      "goal": null
    },
    "successDays": 7,
    "stopRules": {
      "templatePaused": true,
      "qualityLow": true,
      "optoutRate": 0.03,
      "budget": true
    },
    "budgetMicros": null,
    "estimate": {
      "micros": 77824000,
      "currency": "BRL"
    },
    "audienceCount": 1240,
    "header": null,
    "approval": {
      "required": false,
      "requestedTo": null,
      "requestedAt": null,
      "approvedBy": null,
      "approvedAt": null,
      "rejectedReason": null
    },
    "createdBy": null,
    "createdByKind": "api",
    "startedAt": null,
    "paused": null,
    "completedAt": null,
    "createdAt": "2026-10-23T13:02:11.000Z",
    "updatedAt": "2026-10-23T13:02:11.000Z",
    "stats": {
      "audience": 1240,
      "queued": 0,
      "sending": 0,
      "sent": 1216,
      "delivered": 1198,
      "read": 874,
      "failed": 18,
      "skipped": 24,
      "replied": 141,
      "optedOut": 6,
      "successes": 37,
      "costMicros": 77824000,
      "followMicros": 1260000,
      "aiUsdMicros": 0
    }
  }
}
```

### Erros possíveis

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

## Ver uma campanha

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

A campanha com o funil: enviadas, entregues, lidas, respostas, falhas, sucessos e custo (em micros: 1.000.000 = 1 unidade da moeda).

### 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/campaigns/:id" \
  -H "Authorization: Bearer $DONETALK_KEY"
```

### Resposta 200

```json
{
  "campaign": {
    "id": "01a2b3c4-5d6e-7f80-9a1b-2c3d4e5f6a7b",
    "name": "Reativação · outubro",
    "status": "running",
    "channel": {
      "id": "01a0cccc-0000-7000-8000-000000000002",
      "name": "Captei"
    },
    "template": {
      "id": "01a0cad0-0000-7000-8000-000000000002",
      "name": "reativacao_cupom",
      "category": "marketing"
    },
    "variables": [
      {
        "slot": "body.1",
        "source": "first_name",
        "format": "none",
        "fallback": "tudo bem"
      },
      {
        "slot": "body.2",
        "source": "value.cupom",
        "format": "upper",
        "fallback": ""
      }
    ],
    "buttons": [
      {
        "index": 0,
        "action": "route"
      }
    ],
    "audience": {
      "kind": "contacts",
      "contactIds": [
        "01a0d05a-3ee3-75bd-9db5-dc9856f079c8",
        "01a0d05a-3ee3-75bd-9db5-dc9856f079c9"
      ]
    },
    "excludeOpen": true,
    "frequencyDays": 7,
    "startAt": "2026-10-24T12:00:00.000Z",
    "sendWindow": [
      {
        "day": 1,
        "from": "09:00",
        "to": "18:00"
      }
    ],
    "reply": {
      "kind": "team",
      "id": "01a0cb22-89c0-7e02-b96b-3f4731dde701",
      "goal": null
    },
    "successDays": 7,
    "stopRules": {
      "templatePaused": true,
      "qualityLow": true,
      "optoutRate": 0.03,
      "budget": true
    },
    "budgetMicros": null,
    "estimate": {
      "micros": 77824000,
      "currency": "BRL"
    },
    "audienceCount": 1240,
    "header": null,
    "approval": {
      "required": false,
      "requestedTo": null,
      "requestedAt": null,
      "approvedBy": null,
      "approvedAt": null,
      "rejectedReason": null
    },
    "createdBy": null,
    "createdByKind": "api",
    "startedAt": "2026-10-24T12:00:00.000Z",
    "paused": null,
    "completedAt": null,
    "createdAt": "2026-10-23T13:02:11.000Z",
    "updatedAt": "2026-10-23T13:02:11.000Z",
    "stats": {
      "audience": 1240,
      "queued": 0,
      "sending": 0,
      "sent": 1216,
      "delivered": 1198,
      "read": 874,
      "failed": 18,
      "skipped": 24,
      "replied": 141,
      "optedOut": 6,
      "successes": 37,
      "costMicros": 77824000,
      "followMicros": 1260000,
      "aiUsdMicros": 0
    }
  }
}
```

### Erros possíveis

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

## Editar um rascunho

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

Só um rascunho muda. Mande apenas o que muda.

### 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 |
|---|---|---|---|
| `name` | string | não | até 120 caracteres |
| `channelId` | string (uuid) | não | null |
| `templateId` | string (uuid) | não | null |
| `variables` | lista de objeto | não | até 40 |
| `variables[].slot` | string | sim |  |
| `variables[].source` | um de `name`, `first_name`, `phone`, `fixed` · string | sim |  |
| `variables[].value` | string | não | até 500 caracteres |
| `variables[].format` | um de `none`, `title`, `upper`, `lower`, `first` | não | default `"none"` |
| `variables[].fallback` | string | não | até 200 caracteres; default `""` |
| `buttons` | lista de objeto | não | até 10 |
| `buttons[].index` | integer | sim | até 9 |
| `buttons[].action` | um de `route`, `optout`, `none` | sim |  |
| `audience` | objeto | não | null |
| `audience.kind` | um de `segment` | sim |  |
| `audience.segmentId` | string (uuid) | sim |  |
| `audience.conditions` | lista de objeto | sim | até 20 |
| `audience.conditions[].field` | string | sim | até 80 caracteres |
| `audience.conditions[].op` | um de `eq`, `neq`, `has`, `not_has`, `contains`, `empty`, `not_empty`, `gt`, `lt`, `none` | sim |  |
| `audience.conditions[].value` | string · number · boolean · um de `null` | não |  |
| `audience.contactIds` | lista de string (uuid) | não | até 20000; default `[]` |
| `audience.people` | lista de objeto | não | até 20000 |
| `audience.people[].phone` | string | sim | até 40 caracteres |
| `audience.people[].name` | string | não | até 200 caracteres |
| `audience.people[].fields` | object | não |  |
| `audience.people[].tags` | lista de string | não | até 20 |
| `audience.people[].values` | object | não |  |
| `audience.values` | object | não |  |
| `excludeOpen` | boolean | não |  |
| `frequencyDays` | integer | não | até 90; null |
| `startAt` | string (date-time) | não | null |
| `sendWindow` | lista de objeto | não | até 14 |
| `sendWindow[].day` | integer | sim | até 7; mínimo 1 |
| `sendWindow[].from` | string | sim |  |
| `sendWindow[].to` | string | sim |  |
| `reply` | objeto | não |  |
| `reply.kind` | um de `team`, `flow`, `assistant` | não | default `"team"` |
| `reply.id` | string (uuid) | não | default `null`; null |
| `reply.goal` | string | não | até 200 caracteres; default `null`; null |
| `successDays` | integer | não | até 60; mínimo 1 |
| `stopRules` | objeto | não |  |
| `stopRules.templatePaused` | boolean | não | default `true` |
| `stopRules.qualityLow` | boolean | não | default `true` |
| `stopRules.optoutRate` | number | não | até 0.5; mínimo 0.005; default `0.03`; null |
| `stopRules.budget` | boolean | não | default `true` |
| `budgetMicros` | integer | não | até 1000000000000000; null |

### Exemplo de pedido

```bash
curl -X PATCH "https://api.donetalk.com/v1/c/demo/campaigns/:id" \
  -H "Authorization: Bearer $DONETALK_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "name": "Reativação · outubro (2)",
  "frequencyDays": 7
}'
```

### Resposta 200

```json
{
  "campaign": {
    "id": "01a2b3c4-5d6e-7f80-9a1b-2c3d4e5f6a7b",
    "name": "Reativação · outubro",
    "status": "draft",
    "channel": {
      "id": "01a0cccc-0000-7000-8000-000000000002",
      "name": "Captei"
    },
    "template": {
      "id": "01a0cad0-0000-7000-8000-000000000002",
      "name": "reativacao_cupom",
      "category": "marketing"
    },
    "variables": [
      {
        "slot": "body.1",
        "source": "first_name",
        "format": "none",
        "fallback": "tudo bem"
      },
      {
        "slot": "body.2",
        "source": "value.cupom",
        "format": "upper",
        "fallback": ""
      }
    ],
    "buttons": [
      {
        "index": 0,
        "action": "route"
      }
    ],
    "audience": {
      "kind": "contacts",
      "contactIds": [
        "01a0d05a-3ee3-75bd-9db5-dc9856f079c8",
        "01a0d05a-3ee3-75bd-9db5-dc9856f079c9"
      ]
    },
    "excludeOpen": true,
    "frequencyDays": 7,
    "startAt": "2026-10-24T12:00:00.000Z",
    "sendWindow": [
      {
        "day": 1,
        "from": "09:00",
        "to": "18:00"
      }
    ],
    "reply": {
      "kind": "team",
      "id": "01a0cb22-89c0-7e02-b96b-3f4731dde701",
      "goal": null
    },
    "successDays": 7,
    "stopRules": {
      "templatePaused": true,
      "qualityLow": true,
      "optoutRate": 0.03,
      "budget": true
    },
    "budgetMicros": null,
    "estimate": {
      "micros": 77824000,
      "currency": "BRL"
    },
    "audienceCount": 1240,
    "header": null,
    "approval": {
      "required": false,
      "requestedTo": null,
      "requestedAt": null,
      "approvedBy": null,
      "approvedAt": null,
      "rejectedReason": null
    },
    "createdBy": null,
    "createdByKind": "api",
    "startedAt": null,
    "paused": null,
    "completedAt": null,
    "createdAt": "2026-10-23T13:02:11.000Z",
    "updatedAt": "2026-10-23T13:02:11.000Z",
    "stats": {
      "audience": 1240,
      "queued": 0,
      "sending": 0,
      "sent": 1216,
      "delivered": 1198,
      "read": 874,
      "failed": 18,
      "skipped": 24,
      "replied": 141,
      "optedOut": 6,
      "successes": 37,
      "costMicros": 77824000,
      "followMicros": 1260000,
      "aiUsdMicros": 0
    }
  }
}
```

### Erros possíveis

- `400` `template_other_account`
- `401` `unauthorized`
- `403` `insufficient_scope`
- `404` `campaign_not_found`
- `409` `campaign_not_editable`
- `422` `validation_failed`
- `429` `rate_limited`

## Apagar uma campanha

`DELETE /v1/c/{slug}/campaigns/{id}` · Escopos: `campaigns:write`

Rascunhos, canceladas e concluídas. Uma campanha enviando precisa ser cancelada antes.

### 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 DELETE "https://api.donetalk.com/v1/c/demo/campaigns/:id" \
  -H "Authorization: Bearer $DONETALK_KEY"
```

### Resposta 200

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

### Erros possíveis

- `400` `campaign_wrong_status`
- `401` `unauthorized`
- `403` `insufficient_scope`
- `404` `campaign_not_found`
- `422` `validation_failed`
- `429` `rate_limited`

## Duplicar

`POST /v1/c/{slug}/campaigns/{id}/duplicate` · Escopos: `campaigns:write`

Um rascunho novo com a mesma configuração e o mesmo público.

### 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/campaigns/:id/duplicate" \
  -H "Authorization: Bearer $DONETALK_KEY"
```

### Resposta 201

```json
{
  "campaign": {
    "id": "01a2b3c4-5d6e-7f80-9a1b-2c3d4e5f6a7b"
  }
}
```

### Erros possíveis

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

## Pôr a imagem ou documento do cabeçalho

`PUT /v1/c/{slug}/campaigns/{id}/header` · Escopos: `campaigns:write`

Para modelos com cabeçalho de mídia: envie o arquivo em `POST /uploads` e passe o `uploadId`.

### 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 |
|---|---|---|---|
| `uploadId` | string (uuid) | sim |  |

### Exemplo de pedido

```bash
curl -X PUT "https://api.donetalk.com/v1/c/demo/campaigns/:id/header" \
  -H "Authorization: Bearer $DONETALK_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "uploadId": "01a3d1e2-f3a4-7b5c-8d6e-7f8091a2b3c4"
}'
```

### Resposta 200

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

### Erros possíveis

- `401` `unauthorized`
- `403` `insufficient_scope`
- `404` `campaign_not_found`
- `409` `campaign_not_editable`
- `422` `validation_failed`
- `429` `rate_limited`

## Prévia do público

`POST /v1/c/{slug}/campaigns/{id}/audience-preview` · Escopos: `campaigns:read`

Quantos recebem e quantos ficam de fora, por motivo: bloqueado, sem WhatsApp, pediu para sair, repetido, frequência de marketing, conversa aberta.

### 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/campaigns/:id/audience-preview" \
  -H "Authorization: Bearer $DONETALK_KEY"
```

### Resposta 200

```json
{
  "found": 1264,
  "excluded": {
    "blocked": 0,
    "no_whatsapp": 2,
    "opted_out": 18,
    "duplicate": 0,
    "frequency": 4,
    "open_conversation": 0
  },
  "openConversations": 3,
  "receive": 1240,
  "samples": [
    {
      "contactId": "01a0d05a-3ee3-75bd-9db5-dc9856f079c8",
      "name": "Ana Souza",
      "address": "5548999990001"
    }
  ]
}
```

### Erros possíveis

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

## Prévia da mensagem

`POST /v1/c/{slug}/campaigns/{id}/message-preview` · Escopos: `campaigns:read`

Como a mensagem chega para cinco pessoas do público, e quais variáveis ficariam vazias.

### 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/campaigns/:id/message-preview" \
  -H "Authorization: Bearer $DONETALK_KEY"
```

### Resposta 200

```json
{
  "slots": [
    "body.1",
    "body.2"
  ],
  "quickReplies": [
    {
      "index": 0,
      "text": "Quero o cupom"
    }
  ],
  "samples": [
    {
      "contactId": "01a0d05a-3ee3-75bd-9db5-dc9856f079c8",
      "name": "Ana Souza",
      "text": "Oi Ana! Seu cupom ANA10 vale até sexta. Quer usar agora?",
      "missing": []
    }
  ]
}
```

### Erros possíveis

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

## Revisar: custo, conferências e aprovação

`POST /v1/c/{slug}/campaigns/{id}/review` · Escopos: `campaigns:read`

O custo estimado (até), o limite diário do número, os orçamentos, quantas pessoas ficariam sem alguma variável e se a campanha precisará de aprovação.

### 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/campaigns/:id/review" \
  -H "Authorization: Bearer $DONETALK_KEY"
```

### Resposta 200

```json
{
  "estimate": {
    "currency": "BRL",
    "people": 1240,
    "totalMicros": 77824000,
    "markets": [
      {
        "market": "BR",
        "people": 1240,
        "rateMicros": 62760,
        "micros": 77822400
      }
    ]
  },
  "checks": {
    "templateApproved": true,
    "channelActive": true,
    "quality": "GREEN",
    "dailyLimit": 1000,
    "days": 2,
    "budgets": [],
    "campaignBudgetMicros": null,
    "missingVariables": 0
  },
  "approval": {
    "required": false,
    "approvers": []
  }
}
```

### Erros possíveis

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

## Mandar um teste

`POST /v1/c/{slug}/campaigns/{id}/test` · Escopos: `campaigns:write`

Manda a mensagem para um telefone (o seu), sem contar nos números da campanha.

### 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 |
|---|---|---|---|
| `phone` | string | sim | até 40 caracteres |
| `name` | string | não | até 200 caracteres |
| `values` | object | não |  |

### Exemplo de pedido

```bash
curl -X POST "https://api.donetalk.com/v1/c/demo/campaigns/:id/test" \
  -H "Authorization: Bearer $DONETALK_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "phone": "+5548999990009",
  "name": "Leo",
  "values": {
    "cupom": "teste10"
  }
}'
```

### Resposta 200

```json
{
  "ok": true,
  "conversationId": "01a3c0de-7a11-7b22-8c33-9d44e55f6677",
  "messageId": "01a3c0de-8b22-7c33-9d44-0e55f6677889"
}
```

### Erros possíveis

- `401` `unauthorized`
- `403` `insufficient_scope`
- `404` `campaign_not_found`
- `409` `template_not_approved`
- `422` `validation_failed`
- `429` `rate_limited`

## Disparar ou agendar

`POST /v1/c/{slug}/campaigns/{id}/submit` · Escopos: `campaigns:send`

Com `startAt` no futuro, fica agendada; sem, começa agora. Se a regra de aprovação da empresa pedir, a campanha fica `pending_approval` até alguém aprovar no app, a menos que a chave tenha “Disparar sem esperar aprovação”.

### 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 |
|---|---|---|---|
| `approverId` | string (uuid) | não | default `null`; null |

### Exemplo de pedido

```bash
curl -X POST "https://api.donetalk.com/v1/c/demo/campaigns/:id/submit" \
  -H "Authorization: Bearer $DONETALK_KEY" \
  -H "Content-Type: application/json" \
  -d '{}'
```

### Resposta 200

```json
{
  "status": "scheduled"
}
```

### Erros possíveis

- `401` `unauthorized`
- `403` `insufficient_scope`
- `404` `campaign_not_found`
- `409` `campaign_not_editable`
- `409` `template_not_approved`
- `409` `campaign_audience_empty`
- `422` `validation_failed`
- `429` `rate_limited`

## Pausar

`POST /v1/c/{slug}/campaigns/{id}/pause` · Escopos: `campaigns:send`

### 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/campaigns/:id/pause" \
  -H "Authorization: Bearer $DONETALK_KEY"
```

### Resposta 200

```json
{
  "status": "paused"
}
```

### Erros possíveis

- `400` `campaign_wrong_status`
- `401` `unauthorized`
- `403` `insufficient_scope`
- `404` `campaign_not_found`
- `422` `validation_failed`
- `429` `rate_limited`

## Retomar

`POST /v1/c/{slug}/campaigns/{id}/resume` · Escopos: `campaigns:send`

### 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/campaigns/:id/resume" \
  -H "Authorization: Bearer $DONETALK_KEY"
```

### Resposta 200

```json
{
  "status": "running"
}
```

### Erros possíveis

- `400` `campaign_wrong_status`
- `401` `unauthorized`
- `403` `insufficient_scope`
- `404` `campaign_not_found`
- `422` `validation_failed`
- `429` `rate_limited`

## Cancelar

`POST /v1/c/{slug}/campaigns/{id}/cancel` · Escopos: `campaigns:send`

Para de enviar de vez. O que já saiu continua contando nos resultados.

### 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/campaigns/:id/cancel" \
  -H "Authorization: Bearer $DONETALK_KEY"
```

### Resposta 200

```json
{
  "status": "cancelled"
}
```

### Erros possíveis

- `400` `campaign_wrong_status`
- `401` `unauthorized`
- `403` `insufficient_scope`
- `404` `campaign_not_found`
- `422` `validation_failed`
- `429` `rate_limited`

## Reenviar as falhas

`POST /v1/c/{slug}/campaigns/{id}/retry` · Escopos: `campaigns:send`

Volta para a fila quem falhou, todos ou só alguns contatos ou códigos de erro. Falhas que não adianta repetir (número sem WhatsApp, por exemplo) ficam de fora.

### 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 |
|---|---|---|---|
| `contactIds` | lista de string (uuid) | não | até 20000 |
| `errorCodes` | lista de string | não | até 50 |

### Exemplo de pedido

```bash
curl -X POST "https://api.donetalk.com/v1/c/demo/campaigns/:id/retry" \
  -H "Authorization: Bearer $DONETALK_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "errorCodes": [
    "131049"
  ]
}'
```

### Resposta 200

```json
{
  "requeued": 12
}
```

### Erros possíveis

- `400` `campaign_wrong_status`
- `401` `unauthorized`
- `403` `insufficient_scope`
- `404` `campaign_not_found`
- `422` `validation_failed`
- `429` `rate_limited`

## Destinatários, um por um

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

Cada contato com o status da mensagem, a resposta, o botão tocado e o atendimento que ela abriu, com o desfecho. `status` filtra (`sent`, `delivered`, `read`, `failed`, `skipped`, `replied`, `success`); `format=csv` baixa tudo.

### Parâmetros do endereço

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

### Parâmetros de consulta

| Campo | Tipo | Obrigatório | Detalhes |
|---|---|---|---|
| `status` | string | não | até 20 caracteres |
| `limit` | integer | não | até 500; mínimo 1; default `100` |
| `offset` | integer | não | default `0` |
| `format` | um de `json`, `csv` | não | default `"json"` |

### Exemplo de pedido

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

### Resposta 200

```json
{
  "recipients": [
    {
      "contactId": "01a0d05a-3ee3-75bd-9db5-dc9856f079c8",
      "name": "Ana Souza",
      "externalRef": "erp-88213",
      "address": "5548999990001",
      "status": "read",
      "skipReason": null,
      "errorCode": null,
      "sentAt": "2026-10-24T12:00:04.000Z",
      "deliveredAt": "2026-10-24T12:00:06.000Z",
      "readAt": "2026-10-24T12:03:51.000Z",
      "repliedAt": "2026-10-24T12:04:02.000Z",
      "buttonIndex": 0,
      "optedOutAt": null,
      "successAt": null,
      "conversationId": "01a3c0de-7a11-7b22-8c33-9d44e55f6677",
      "nextAttemptAt": null,
      "conversation": {
        "status": "closed",
        "handler": "human",
        "lastInboundAt": "2026-10-24T12:09:10.000Z",
        "lastMessageAt": "2026-10-24T12:20:41.000Z",
        "lastMessageBy": "member",
        "closedAt": "2026-10-24T12:20:41.000Z",
        "closedBy": "member",
        "outcome": {
          "code": "converted",
          "category": "success",
          "label": {
            "pt-BR": "Venda",
            "en": "Sale",
            "es": "Venta"
          },
          "note": "Fechou o plano anual com o cupom ANA10."
        }
      },
      "tags": [
        {
          "id": "01a12150-3610-7c00-b680-188c2b4c7313",
          "name": {
            "pt-BR": "VIP",
            "en": "VIP",
            "es": "VIP"
          }
        }
      ]
    }
  ]
}
```

### Erros possíveis

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

## Falhas, botões e cliques

`GET /v1/c/{slug}/campaigns/{id}/insights` · Escopos: `campaigns: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/campaigns/:id/insights" \
  -H "Authorization: Bearer $DONETALK_KEY"
```

### Resposta 200

```json
{
  "failures": [
    {
      "code": "131026",
      "count": 9,
      "waiting": 0
    }
  ],
  "skipped": [
    {
      "reason": "opted_out",
      "count": 18
    }
  ],
  "buttons": [
    {
      "index": 0,
      "text": "Quero o cupom",
      "taps": 96
    }
  ],
  "links": [],
  "perHour": [
    {
      "hour": "2026-10-24T12:00:00.000Z",
      "count": 640
    }
  ]
}
```

### Erros possíveis

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

