Introduction
API pública de integração do Br Envio: cadastrar e atualizar contatos (e tags) via Bearer API token.
O que esta API faz hoje
Este portal documenta o subset público para integradores (CRM, loja, ERP, legado).
Hoje as operações publicadas são:
POST /api/v1/integration/contacts— cria ou atualiza um contato pelo e-mail; pode anexar ou substituir tags e preencher campos tipados e telefone./api/v1/integration/tags— CRUD do catálogo de tags (listar, criar, renomear, excluir).
Campanhas, disparo, modelos, setup de domínio, billing e Super Admin não entram aqui — usam o painel (JWT). Ver seção Fora deste portal.
Autenticação
Todas as rotas deste portal usam API token (não o login do painel).
- No painel: Conta → Tokens de API → criar token e copiar uma vez.
- Enviar o cabeçalho:
Authorization: Bearer <seu_token>. - Rate limit: 60 requisições/minuto por token.
Guia leigo: Tokens de API.
Base URL
Produção: https://api.brenvio.com.br
Exemplo completo: POST https://api.brenvio.com.br/api/v1/integration/contacts
Envelope JSON
Sucesso:
{ "success": true, "data": { }, "message": "..." }
Erro:
{ "success": false, "error": { "code": "CODIGO", "message": "texto legível" } }
Códigos comuns no upsert: UNAUTHORIZED, CONTACT_BLOCKLISTED, CONTACT_SUPPRESSED, UNKNOWN_FIELD_SLUG, RATE_LIMIT_EXCEEDED, VALIDATION_ERROR.
Idioma
Opcional: Accept-Language: pt-BR | en | es (mensagens de erro/sucesso).
Contatos (upsert)
Chave de identidade: e-mail (normalizado em minúsculas).
| Campo | Obrigatório | Comportamento |
|---|---|---|
email |
sim | Cria se novo; atualiza se já existir |
name |
não | Nome de exibição |
country_code + phone_number |
não | Telefone nativo (DDI + dígitos). Default DDI 55 se vier telefone sem DDI |
phone |
não | Alternativa em uma string; o servidor normaliza |
tags |
não | Array de nomes; cria a tag se faltar |
tag_match |
não | append (default) = anexa sem remover; replace = o array enviado substitui o conjunto atual |
fields |
não | Objeto { "slug": valor } dos campos da base; upsert parcial (só os slugs enviados) |
Higiene (não negociável):
- E-mail na lista de bloqueio do cliente → rejeitado (
CONTACT_BLOCKLISTED). - E-mail/domínio na supressão global → rejeitado (
CONTACT_SUPPRESSED). - Contato
unsubscribedousuppressednão é reativado pelo upsert.
Resposta inclui data.created (true = 201 criado, false = 200 atualizado).
Tags
Catálogo (CRUD)
| Método | Path | Uso |
|---|---|---|
GET |
/api/v1/integration/tags |
Listar (opcional ?search= e per_page) |
POST |
/api/v1/integration/tags |
Criar { "name": "VIP" } |
GET |
/api/v1/integration/tags/{id} |
Detalhe |
PATCH/PUT |
/api/v1/integration/tags/{id} |
Renomear |
DELETE |
/api/v1/integration/tags/{id} |
Excluir (remove vínculos; contatos ficam) |
Vincular tags a contatos
No upsert de contatos:
"tags": ["Lead CRM", "VIP"]— cria nomes que não existirem.tag_matchomitido ouappend— anexa (não apaga tags já no contato).tag_match: "replace"— o array vira o conjunto canônico (CRM manda a verdade).
Gerenciar tags na UI: ajuda — Tags.
Campos tipados
Os slugs de fields precisam existir em Conta → Campos da base no painel. Slug desconhecido → UNKNOWN_FIELD_SLUG.
Datas no valor: preferir AAAA-MM-DD.
Fora deste portal (painel)
Estas capacidades existem no produto, mas não têm endpoint público com API token no F1:
| Capacidade | Onde usar |
|---|---|
| Criar campanha / editor / modelos | Painel → Campanhas / Modelos |
| Enviar teste e disparar campanha | Painel → Testar e disparar |
| Métricas de envio | Painel → Envios |
| Import/export CSV | Painel → Contatos |
| Setup de domínio / DNS | Painel → Setup de envio |
| CRUD completo de contatos (lista, delete) | Painel (API token: upsert + tags) |
| Tokens (criar/revogar) | Painel → Conta → Tokens de API |
Quando o PO abrir PUBLISH de CRUD contatos/tags ou leitura de campanhas, este portal é regenerado (DOC 18).
Authenticating requests
To authenticate requests, include an Authorization header with the value "Bearer {YOUR_API_TOKEN}".
All authenticated endpoints are marked with a requires authentication badge in the documentation below.
Crie o token em Conta → Tokens de API no painel (https://painel.brenvio.com.br/settings/api-tokens). O valor em texto só aparece na criação.
Contact Integration
Upsert de contatos para CRM e sistemas externos.
Autenticação: Authorization: Bearer <api_token> (token gerado em Conta → Tokens de API).
Rate limit: 60 req/min por token. Envelope { success, data } / { success: false, error }.
Upsert contact
requires authentication
Cria ou atualiza um contato pelo e-mail. Tags são anexadas por nome (criadas se não existirem).
Campos tipados (fields) são upsert parcial — só os slugs enviados. Não reativa contatos
unsubscribed ou suppressed. Respeita blocklist do cliente e suppressão global.
Example request:
curl --request POST \
"https://api.brenvio.com.br/api/v1/integration/contacts" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"email\": \"helena@crm.test\",
\"name\": \"Helena\",
\"country_code\": \"55\",
\"phone_number\": \"11988887777\",
\"phone\": \"+55 11 98888-7777\",
\"tags\": [
\"Lead CRM\",
\"VIP\"
],
\"tag_match\": \"append\",
\"fields\": {
\"empresa\": \"Acme\"
}
}"
const url = new URL(
"https://api.brenvio.com.br/api/v1/integration/contacts"
);
const headers = {
"Authorization": "Bearer {YOUR_API_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"email": "helena@crm.test",
"name": "Helena",
"country_code": "55",
"phone_number": "11988887777",
"phone": "+55 11 98888-7777",
"tags": [
"Lead CRM",
"VIP"
],
"tag_match": "append",
"fields": {
"empresa": "Acme"
}
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://api.brenvio.com.br/api/v1/integration/contacts';
$response = $client->post(
$url,
[
'headers' => [
'Authorization' => 'Bearer {YOUR_API_TOKEN}',
'Content-Type' => 'application/json',
'Accept' => 'application/json',
],
'json' => [
'email' => 'helena@crm.test',
'name' => 'Helena',
'country_code' => '55',
'phone_number' => '11988887777',
'phone' => '+55 11 98888-7777',
'tags' => ['Lead CRM', 'VIP'],
'tag_match' => 'append',
'fields' => ['empresa' => 'Acme'],
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));Example response (200, updated):
{
"success": true,
"message": "Contato atualizado via integração.",
"data": {
"id": 1,
"email": "helena@crm.test",
"created": false
}
}
Example response (201, created):
{
"success": true,
"message": "Contato criado via integração.",
"data": {
"id": 1,
"email": "helena@crm.test",
"name": "Helena",
"status": "active",
"tags": [
{
"id": 1,
"name": "VIP"
}
],
"fields": {
"empresa": "Acme"
},
"created": true
}
}
Example response (401, unauthorized):
{
"success": false,
"error": {
"code": "UNAUTHORIZED",
"message": "Autenticação necessária."
}
}
Example response (422, blocklisted):
{
"success": false,
"error": {
"code": "CONTACT_BLOCKLISTED",
"message": "Este e-mail ou domínio está na lista de bloqueio e não pode ser cadastrado."
}
}
Example response (422, suppressed):
{
"success": false,
"error": {
"code": "CONTACT_SUPPRESSED",
"message": "Este e-mail ou domínio está na lista de supressão e não pode ser cadastrado."
}
}
Example response (422, unknown_field):
{
"success": false,
"error": {
"code": "UNKNOWN_FIELD_SLUG",
"message": "Slug de campo desconhecido."
}
}
Example response (429, rate_limited):
{
"success": false,
"error": {
"code": "RATE_LIMIT_EXCEEDED",
"message": "Limite de requisições excedido."
}
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Tags
Catálogo de marcadores (tags) da conta.
Autenticação neste portal: Authorization: Bearer <api_token> nas rotas /api/v1/integration/tags*.
Rate limit: 60 req/min por token. Envelope { success, data } / { success: false, error }.
List tags
requires authentication
Lista paginada de tags. Busca opcional por nome (search).
Create tag
requires authentication
Cria uma tag pelo nome. Nome duplicado (case-insensitive) → validação 422.
Get tag
requires authentication
Update tag
requires authentication
Renomeia a tag. Não altera vínculos com contatos (só o nome).
Delete tag
requires authentication
Remove a tag e os vínculos com contatos (cascade). Os contatos permanecem.