> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.callix.dev.br/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.callix.dev.br/_mcp/server.

# Usando a API para importação de contatos

Para importar contatos usando a API é preciso utilizar a interface do sistema para gerar um\
[token de acesso](/introducao/visao-geral#autenticação) da API **e criar uma campanha**.

Cumprindo esses requisitos, siga os passos descritos abaixo:

## 1. Criar lista de campanha

> **Note**
>
> Caso já tenha criado uma lista de campanha pela interface ou até mesmo pela API e já tenha um ID de lista de campanha, siga para o próximo passo.

A lista de campanha agrupa contatos dentro de uma campanha. E pode ser criada tanto pela interface quanto pela API.

#### Exemplo de chamada:

```bash
curl -X POST "https://sua-conta.callix.com.br/api/v1/campaign_lists" \
  -H "Authorization: Bearer SEU_TOKEN"
```

#### Exemplo de resposta:

```json
{
  "data": {
    "type": "campaign_lists",
    "id": "146",
    "attributes": {
      "name": "Lista de campanha teste",
      "status": 2
    },
    "links": {
      "self": "/api/v1/campaign_lists/146"
    },
    "relationships": {
      "campaign": {
        "links": {
          "self": "/api/v1/campaign_lists/146/relationships/campaign",
          "related": "/api/v1/campaign_lists/146/campaign"
        }
      }
    }
  }
}
```

No exemplo acima, é criada uma lista de nome `Lista de campanha teste` na campanha de
**ID 1**. No retorno temos o **ID 146**, atribuído para a lista recém criada e que vamos
utilizar para importar contatos.

## 2. Importar contatos em uma lista

Essa chamada adiciona contatos a uma lista de contatos. **O processamento dessa chamada é feito de forma assíncrona.**

#### Exemplo de chamada:

```bash
curl -X POST "https://sua-conta.callix.com.br/api/v1/campaign_contacts_async" \
  -H "Authorization: Bearer SEU_TOKEN"
```

Na chamada, no atributo `import_data`, deve-se enviar no mínimo os campos obrigatórios do formulário associado à campanha.
O valor da chave é o próprio nome do campo.

> **Note**
>
> A API é **case sensitive**. Portanto, no atributo `import_data` os dados tem de estar com as chaves exatamente iguais ao cadastrado no formulário.
> Ou seja, se no formulário temos cadastrado o campo 'NOME' temos de ter `import_data: [{NOME: 'Nome Fictício'}]`

No caso de exemplo, apenas os campos `ID` e `Celular` são obrigatórios na importação:

![Formulário](/_fern-img/81b77f115085ff01cba20337bac91bcea4de991e2b7a84802cfb570acb3e7e92.webp)

#### Exemplo de resposta:

```json
{
  "data": {
    "type": "campaign_contacts_async",
    "id": "1",
    "attributes": {
      "remove_duplicated_phones": true,
      "status": 1,
      "import_data": []
    },
    "links": {
      "self": "/api/v1/campaign_contacts_async/1"
    },
    "relationships": {
      "campaign_list": {
        "links": {
          "self": "/api/v1/campaign_contacts_async/1/relationships/campaign_list",
          "related": "/api/v1/campaign_contacts_async/1/campaign_list"
        }
      }
    }
  }
}
```

Como o processamento é feito de forma assíncrona, no retorno da chamada temos o status da importação:

```json startLine=5
"attributes": {
  "remove_duplicated_phones": true,
  "status": 1 // o valor 1 indica que o status é pendente
}
```

E também um ID do serviço de importação (job) que tratará a importação assíncrona:

```json startLine=15
"links": {
  "self": "/api/v1/campaign_contacts_async/1" // Este ID será usado no próximo passo
}
```

Usando o ID (no exemplo, ID `1`), é possível consultar o progresso da importação.

> **Note**
>
> Solicitações de importação feitas pela API entram em uma fila de processamento e são feitas assim que possível dependendo da disponibilidade dos serviços de importação. Também é processado apenas uma solicitação por vez e por cliente.

## 3. Consultar progresso da importação de contatos

Essa chamada retorna a situação da importação.
Para usá-la é necessário usar o ID do job de importação obtida no fim do passo 2 acima.

#### Exemplo de chamada:

```bash
curl -X GET "https://sua-conta.callix.com.br/api/v1/campaign_contacts_async/1" \
  -H "Authorization: Bearer SEU_TOKEN"
```

#### Exemplo de resposta:

```json
{
  "data": {
    "type": "campaign_contacts_async",
    "id": "1",
    "attributes": {
      "remove_duplicated_phones": true,
      "status": 3,
      "import_result": []
    },
    "links": {
      "self": "/api/v1/campaign_contacts_async/1"
    },
    "relationships": {
      "campaign_list": {
        "links": {
          "self": "/api/v1/campaign_contacts_async/1/relationships/campaign_list",
          "related": "/api/v1/campaign_contacts_async/1/campaign_list"
        }
      }
    }
}
```

O campo status pode assumir os seguintes valores:

| código | significado |
| ------ | ----------- |
| `1`    | Pendente    |
| `2`    | Executando  |
| `3`    | Completada  |
| `4`    | Falha       |

No caso do exemplo, a solicitação foi completada com sucesso.

## 4. Baixar arquivo de resultado da importação

Após a conclusão da importação, é possível baixar um arquivo contendo os erros e avisos que ocorreram durante o processamento. Este endpoint retorna o arquivo de resultado nos formatos CSV (padrão) ou JSON.

> **Note**
>
> Este endpoint só está disponível para importações com status `3` (Completada) que possuam erros ou avisos. Importações com 100% de sucesso não geram arquivo de resultado.

#### Exemplo de chamada (formato CSV):

```bash
curl -X GET "https://sua-conta.callix.com.br/api/v1/campaign_contacts_async/1/result?format=csv" \
  -H "Authorization: Bearer SEU_TOKEN"
```

#### Exemplo de chamada (formato JSON):

```bash
curl -X GET "https://sua-conta.callix.com.br/api/v1/campaign_contacts_async/1/result?format=json" \
  -H "Authorization: Bearer SEU_TOKEN"
```

#### Parâmetros:

| Parâmetro | Tipo         | Obrigatório | Valores       | Descrição                                             |
| --------- | ------------ | ----------- | ------------- | ----------------------------------------------------- |
| `format`  | query string | Não         | `csv`, `json` | Define o formato do arquivo de retorno. Padrão: `csv` |

#### Resposta:

A resposta será o download de um arquivo nos formatos:

* **CSV**: Arquivo de texto delimitado por ponto e vírgula (`;`) com os erros/avisos
* **JSON**: Array de objetos JSON com os erros/avisos

#### Possíveis respostas:

| Código HTTP | Descrição                                                                    |
| ----------- | ---------------------------------------------------------------------------- |
| `200`       | Sucesso - retorna o arquivo CSV ou JSON com os erros/avisos                  |
| `202`       | Importação ainda está sendo processada - retorna JSON com status e progresso |
| `400`       | Formato inválido (valores aceitos: `csv`, `json`)                            |
| `404`       | Importação não encontrada, falhou ou não possui arquivo de resultado         |

#### Exemplo de resposta 200 (JSON com erros):

```json
[
  {
    "id": "1",
    "nome": "João Silva",
    "telefone": "(12)99999-9999",
    "email": "joao@example.com",
    "Erros (contato não importado)": "Contato duplicado",
    "Avisos": "",
    "Telefones com baixa probabilidade de atendimento": ""
  },
  {
    "id": "2",
    "nome": "Maria Santos",
    "telefone": "(11)98888-8888",
    "email": "maria@example.com",
    "Erros (contato não importado)": "",
    "Avisos": "Contato existente sobreescrito na mesma lista",
    "Telefones com baixa probabilidade de atendimento": "(11)98888-8888"
  }
]
```

#### Caso a importação ainda esteja sendo processada (202 ACCEPTED):

```json
{
  "status": "in_progress",
  "progress": 45,
  "total_count": 1000,
  "success_count": 450,
  "error_count": 10,
  "warning_count": 5,
  "message": "The import is still being processed. Please try again later."
}
```

#### Caso a importação ainda esteja pendente (202 ACCEPTED):

```json
{
  "status": "pending",
  "total_count": 0,
  "success_count": 0,
  "error_count": 0,
  "warning_count": 0,
  "message": "The import has not started yet. Please try again later."
}
```

### Tipos de erros que podem aparecer no resultado

| Erro                                                                                                        | Descrição                                                                             |
| ----------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------- |
| Contato duplicado                                                                                           | O contato já existe no arquivo de importação (baseado nos campos únicos configurados) |
| O contato não possui nenhum número de telefone válido                                                       | Nenhum telefone válido foi encontrado nos campos de telefone                          |
| Todos os telefones do contato foram descartados por possuírem baixa probabilidade de atendimento            | Todos os telefones foram removidos pelo filtro de qualidade de telefones              |
| Contato já existe na lista de contatos                                                                      | O contato já foi importado anteriormente e a opção de sobrescrever está desabilitada  |
| Telefone repetido: A coluna \[nome] contém um telefone que já foi importado anteriormente para esse contato | O telefone já existe no contato e a opção de remover duplicados está desabilitada     |

### Tipos de avisos que podem aparecer no resultado

| Aviso                                                                                                                  | Descrição                                                                              |
| ---------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- |
| O telefone da coluna "\[nome]" foi descartado por ter uma baixa probabilidade de atendimento                           | Um telefone específico foi removido pelo filtro de qualidade                           |
| Contato existente sobreescrito em outra lista (\[nome da lista])                                                       | O contato foi atualizado, mas ele pertencia a outra lista                              |
| Contato existente sobreescrito na mesma lista                                                                          | O contato foi atualizado na mesma lista                                                |
| Telefone repetido descartado: A coluna \[nome] contém um telefone que já foi importado anteriormente para esse contato | O telefone duplicado foi removido porque a opção de remover duplicados está habilitada |