> ## Documentation Index
> Fetch the complete documentation index at: https://docs.polymorfa.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Construa (build) um público

> Crie uma lista reutilizável de números e variáveis de modelo a partir de membros enviados na requisição ou de um arquivo CSV e mantenha essa lista atualizada.

Um público é uma lista de números de telefone, cada um com as próprias
variáveis de modelo, que pertence à sua equipe. Qualquer campanha em qualquer
projeto dessa equipe pode usá-lo. A Polymorfa armazena os membros, faz a
contagem e os copia para a campanha quando ela é lançada.

Públicos são um recurso da equipe. Use uma chave de API da equipe:
`campaigns:read` para ler e `campaigns:manage` para alterar. Tokens de projeto
são recusados em todas as rotas de público.

Para guardar atributos e declarações de consentimento fornecidos por você para
cada número de telefone, consulte
[Gerenciar perfis de público](/guides/campaigns/audience-profiles).

## Crie um público com membros na requisição

Envie até 1.000 membros no corpo da requisição.

```bash theme={null}
curl -X POST "https://api.polymorfa.com/platform/audiences" \
  -H "Authorization: Bearer $POLYMORFA_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "September launch",
    "members": [
      { "phone": "+14155550100", "variables": { "first_name": "Ada", "plan": "pro" } },
      { "phone": "+442071838750", "variables": { "first_name": "Alan" } }
    ]
  }'
```

A resposta traz o público e o que a importação fez com os dados enviados:

```json theme={null}
{
  "data": {
    "id": "3b2f0c4e-6c1a-4a9b-9a53-6b7c9d0e1f22",
    "name": "September launch",
    "source": "manual",
    "recipientCount": 2,
    "duplicateCount": 0,
    "invalidCount": 0,
    "invalidRows": []
  }
}
```

`recipientCount` é o número de membros que a Polymorfa armazenou. Uma contagem
enviada na requisição é ignorada.

## Importe um arquivo CSV

A importação de um arquivo leva três requisições: peça uma URL de upload,
envie o arquivo e crie o público a partir do arquivo armazenado.

Peça uma URL de upload. Ela é de uso único e expira pouco depois de ser
emitida.

```bash theme={null}
curl -X POST "https://api.polymorfa.com/platform/audiences/uploads" \
  -H "Authorization: Bearer $POLYMORFA_KEY"
```

Envie o arquivo para essa URL. A resposta traz `storageId`.

```bash theme={null}
curl -X POST "$UPLOAD_URL" \
  -H "Content-Type: text/csv" \
  --data-binary @contacts.csv
```

Crie o público a partir do arquivo armazenado, passando `storageId` como
`fileId` e indicando as colunas.

```bash theme={null}
curl -X POST "https://api.polymorfa.com/platform/audiences" \
  -H "Authorization: Bearer $POLYMORFA_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "September launch",
    "fileId": "'"$STORAGE_ID"'",
    "mapping": {
      "phone": "Mobile",
      "variables": { "first_name": "First name", "plan": "Plan" }
    }
  }'
```

`mapping.phone` indica a coluna que contém o número. `mapping.variables`
associa o nome de cada variável de modelo à coluna que fornece o valor. Os
nomes de coluna são comparados primeiro de forma exata e, depois, sem
diferenciar maiúsculas de minúsculas.

A Polymorfa lê o arquivo no servidor. O arquivo precisa estar em UTF-8 e ter
uma linha de cabeçalho. O separador é detectado pela linha de cabeçalho:
vírgula, ponto e vírgula ou tabulação, e vírgula quando a linha é ambígua.
Campos entre aspas, aspas duplicadas dentro de um campo entre aspas, quebras de
linha dentro de um campo entre aspas e finais de linha LF, CRLF ou CR são lidos
corretamente. Linhas em branco são ignoradas.

Envie `members` ou `fileId` com `mapping`. Uma requisição com os dois é
recusada.

## Regras de números e variáveis

| Regra | Valor |
| - | - |
| Formato do número | Internacional. Espaços, pontos, hifens e parênteses são ignorados; um `00` no início é lido como `+`; dígitos sem `+` são lidos como se já incluíssem o código do país |
| Tamanho do número | De 8 a 15 dígitos, incluindo o código do país, e um tamanho possível para esse país |
| Variáveis por membro | No máximo 50 |
| Nome da variável | Começa com uma letra, um dígito ou `_`, seguido de até 63 caracteres entre letras, dígitos, `_`, `.` e `-` |
| Valor da variável | Uma string, um número ou um booleano, armazenado como string de no máximo 1.024 caracteres |
| Membros por requisição | No máximo 1.000 |
| Linhas de dados por importação de arquivo | No máximo 100.000 |

Um número nacional sem código do país não pode ser resolvido e é informado
como inválido. Um arquivo com mais de 100.000 linhas de dados é recusado com
`413`: divida-o em arquivos menores e importe cada um.

## Veja o que a importação rejeitou

Cada criação e cada acréscimo informam as linhas que não foram armazenadas,
para que você corrija e reenvie apenas essas linhas:

| Campo | Significado |
| - | - |
| `recipientCount` | Membros no público após a requisição |
| `duplicateCount` | Entradas válidas ignoradas porque o número se repetiu na requisição ou já está no público |
| `invalidCount` | Entradas que falharam na validação |
| `invalidRows` | Até 20 exemplos, cada um com `row` e `reason` |

`reason` é `missing_phone`, `invalid_phone`, `invalid_variables` ou
`invalid_entry`. Para membros enviados na requisição, `row` é a posição no
array, começando em 1. Para um arquivo, `row` é o número da linha na planilha,
em que o cabeçalho é a linha 1.

## Mantenha um público atualizado

```bash theme={null}
# Add up to 1,000 members
curl -X POST "https://api.polymorfa.com/platform/audiences/$LIST_ID/members" \
  -H "Authorization: Bearer $POLYMORFA_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "members": [{ "phone": "+14155550101", "variables": { "first_name": "Grace" } }] }'

# Page through members in the order they were added
curl "https://api.polymorfa.com/platform/audiences/$LIST_ID/members?limit=100" \
  -H "Authorization: Bearer $POLYMORFA_KEY"

# Remove one member
curl -X DELETE "https://api.polymorfa.com/platform/audiences/$LIST_ID/members/%2B14155550101" \
  -H "Authorization: Bearer $POLYMORFA_KEY"
```

A listagem de membros usa paginação por cursor: `limit` vai de 1 a 100, com
padrão 25, e `page.nextCursor` traz a próxima página até `page.hasMore` ser
`false`. Adicionar um número que já é membro faz com que ele seja ignorado e
informado em `duplicateCount`. Remover um membro altera apenas o público. Uma
campanha que já foi lançada mantém os destinatários que copiou.

Duplicar uma campanha vinculada a um público cria um rascunho com esse mesmo
público. A cópia recebe os membros do público quando é lançada, incluindo as
mudanças de membros desde o lançamento original. Uma campanha sem público
copia os destinatários dela para o novo rascunho.

## Redirecione destinatários de uma campanha anterior

Construa (build) um público com os destinatários de uma campanha que você já
enviou, filtrados pelo que aconteceu com eles, e envie a essas pessoas uma
campanha de acompanhamento.

```bash theme={null}
curl -X POST "https://api.polymorfa.com/platform/audiences/from-campaign" \
  -H "Authorization: Bearer $POLYMORFA_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Spring launch: did not read",
    "campaignId": "'"$CAMPAIGN_ID"'",
    "outcome": "not_read"
  }'
```

| `outcome` | Destinatários selecionados |
| - | - |
| `delivered` | O aparelho do destinatário confirmou a entrega |
| `not_delivered` | Enviada, sem confirmação de entrega |
| `read` | Leram a mensagem |
| `not_read` | Enviada e não lida, incluindo mensagens nunca entregues |
| `replied` | Responderam à mensagem |
| `not_replied` | Enviada, e nenhuma resposta foi atribuída ao destinatário |
| `failed` | Envios com falha confirmada; entregas incertas e resultados ambíguos mais antigos ficam de fora |

Os resultados de leitura dependem das confirmações de leitura do destinatário:
quem as desativou nunca fica como `read`. As respostas são atribuídas da mesma
forma que nas
[análises da campanha](/pt-br/guides/campaigns/send-a-campaign#acompanhe-o-envio).

A resposta é o novo público, com `source` definido como `campaign`, e mais:

| Campo | Significado |
| - | - |
| `recipientCount` | Membros no novo público |
| `matchedCount` | Destinatários da campanha de origem com esse resultado |
| `optedOutCount` | Destinatários correspondentes deixados de fora porque o número está na lista de opt-outs da equipe |
| `sourceCampaignId`, `outcome` | A origem usada para criar o público |

O público é um retrato do momento em que a requisição é executada.
Confirmações, leituras e respostas que chegam depois não o alteram; crie um
novo público para incluí-las. Cada membro mantém as variáveis de modelo que
tinha na campanha de origem. Os números na lista de opt-outs ficam de fora
agora, e qualquer número que fizer opt-out antes do lançamento da campanha de
acompanhamento também é ignorado no lançamento. Um número cujo
[perfil de público](/guides/campaigns/audience-profiles) foi excluído nos
últimos 30 dias também fica de fora.

`projectId` é opcional. Quando você o envia, a campanha precisa pertencer a
esse projeto. A requisição exige uma chave de API da equipe com
`campaigns:manage`, como as outras escritas em públicos. `404` significa que a
campanha não está na sua equipe (ou não está em `projectId`). `409` significa
que nenhum destinatário fora da lista de opt-outs tem esse resultado, e nada é
criado.

No Console, abra a campanha e escolha **Redirecionar…** no menu de ações. A
ação fica disponível depois que a campanha é lançada.

## Tente novamente com segurança

A criação de um público e a adição de membros aceitam o cabeçalho
`Idempotency-Key`. Envie esse cabeçalho para que uma nova tentativa após um
timeout ou uma resposta perdida não crie um segundo público nem informe os
membros da primeira requisição como duplicados.

```bash theme={null}
curl -X POST "https://api.polymorfa.com/platform/audiences/$LIST_ID/members" \
  -H "Authorization: Bearer $POLYMORFA_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: crm-sync-2026-09-24-batch-7" \
  -d '{ "members": [{ "phone": "+14155550102" }] }'
```

| Nova tentativa em até 24 horas | Resposta |
| - | - |
| Adicionar membros: mesma chave, mesma credencial, mesmo `Polymorfa-Version` e mesmo corpo | `200` com `Idempotent-Replayed: true` e as contagens da primeira requisição. Nada é gravado de novo |
| Criar: mesma chave, mesma credencial, mesmo `Polymorfa-Version` e mesmo corpo | `200` com `Idempotent-Replayed: true`, o público como está agora e as contagens de importação da primeira requisição. Nada é gravado de novo |
| Mesma chave, corpo diferente | `409 idempotency_conflict` |
| Enviada enquanto a primeira requisição ainda está em execução | Aguarda a primeira requisição e retorna o resultado dela |
| Depois que a primeira requisição falhou | Executa de novo. Uma requisição que falhou não deixa registro da chave |

Um acréscimo repetido retorna as contagens da primeira requisição, não o
tamanho atual do público. Uma criação repetida retorna o público como está
agora, com `duplicateCount`, `invalidCount` e `invalidRows` da primeira
requisição. Se esse público foi excluído, a nova tentativa retorna
`409 idempotency_completed`. Cada nova tentativa verifica seu acesso de novo,
então uma nova tentativa para um público excluído, ou com uma credencial que
perdeu o acesso, falha. As chaves valem apenas para a credencial que as
enviou.

## Use o público em uma campanha

Defina `recipientListId` na campanha. Os membros são copiados para a campanha
quando ela é lançada, os números na lista de opt-outs da equipe são ignorados e
`recipientCount` é definido a partir das linhas que foram de fato criadas.
Consulte [Envie uma campanha](/pt-br/guides/campaigns/send-a-campaign) e
[Opt-outs e respostas STOP](/pt-br/guides/campaigns/opt-outs).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.