SyncroCentral de Ajuda
No se encontraron resultados
Acessar Syncro

Criar lead via API

Actualizado el 30 de abril de 2026

Caso de uso mais comum da API Syncro: criar leads programaticamente a partir de form externo, sistema legado, importação batch ou integração custom. Esse artigo cobre POST /leads e POST /leads/upsert com exemplos completos.

Pré-requisitos

  • API Key gerada. Veja Gerar API Key.
  • Pipeline + etapa cadastrados no Syncro.
  • Cliente HTTP (cURL, Postman, Node, Python, etc).

Endpoint

POST https://app.syncro.chat/api/v1/leads

Headers obrigatórios

X-API-Key: crm_a1b2c3...
Content-Type: application/json
Accept: application/json

Payload mínimo

Apenas campos obrigatórios:

{
 "name": "João Silva",
 "pipeline_id": 1,
 "stage_id": 5
}

💡 Dica: pra descobrir pipeline_id e stage_id, faça GET /api/v1/pipelines antes.

Payload completo

Todos os campos suportados:

{
 "name": "João Silva",
 "phone": "+5511987654321",
 "email": "[email protected]",
 "company": "Acme Corp",
 "value": 5000.50,
 "source": "site-form",
 "notes": "Veio do formulário de contato",
 "tags": ["prospect", "premium", "indicacao"],
 "pipeline_id": 1,
 "stage_id": 5,
 "assigned_to": 3,
 "utm_source": "google",
 "utm_medium": "cpc",
 "utm_campaign": "summer_2026",
 "utm_term": "crm-vendas",
 "utm_content": "banner-azul",
 "fbclid": "fb_click_id_xyz",
 "gclid": "google_click_id_abc",
 "custom_fields": {
 "porte_empresa": "media",
 "setor": "Tecnologia",
 "receita_anual": 500000
 }
}

Validações

Campo Regra
name required, max 255 chars
phone ou email pelo menos um obrigatório
value numérico, ≥ 0
pipeline_id required, deve existir
stage_id required, deve existir e pertencer ao pipeline
assigned_to nullable, deve existir como user do tenant
tags array de strings
notes text, max 1MB
custom_fields object com field_name => value

Resposta de sucesso

Status 201 Created:

{
 "success": true,
 "data": {
 "id": 1234,
 "name": "João Silva",
 "phone": "+5511987654321",
 "email": "[email protected]",
 "company": "Acme Corp",
 "value": 5000.50,
 "source": "site-form",
 "status": "active",
 "pipeline_id": 1,
 "stage_id": 5,
 "assigned_to": 3,
 "tags": ["prospect", "premium", "indicacao"],
 "utm_source": "google",
 "utm_medium": "cpc",
 "utm_campaign": "summer_2026",
 "created_at": "2026-04-30T14:30:00Z",
 "updated_at": "2026-04-30T14:30:00Z"
 }
}

Resposta de erro

422 Validation error:

{
 "success": false,
 "error": "The given data was invalid.",
 "errors": {
 "name": ["O campo nome é obrigatório."],
 "stage_id": ["O stage_id selecionado não existe."]
 }
}

Exemplos por linguagem

cURL

curl -X POST "https://app.syncro.chat/api/v1/leads" \
 -H "X-API-Key: crm_a1b2c3..." \
 -H "Content-Type: application/json" \
 -d '{
 "name": "João Silva",
 "phone": "+5511987654321",
 "email": "[email protected]",
 "pipeline_id": 1,
 "stage_id": 5,
 "tags": ["prospect"],
 "source": "site-form"
 }'

PHP

<?php
$payload = [
 'name' => 'João Silva',
 'phone' => '+5511987654321',
 'email' => '[email protected]',
 'pipeline_id' => 1,
 'stage_id' => 5,
 'tags' => ['prospect'],
 'source' => 'site-form',
];

$ch = curl_init('https://app.syncro.chat/api/v1/leads');
curl_setopt_array($ch, [
 CURLOPT_RETURNTRANSFER => true,
 CURLOPT_POST => true,
 CURLOPT_POSTFIELDS => json_encode($payload),
 CURLOPT_HTTPHEADER => [
 'X-API-Key: crm_a1b2c3...',
 'Content-Type: application/json',
 'Accept: application/json',
 ],
]);
$response = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

if ($status === 201) {
 $lead = json_decode($response, true)['data'];
 echo "Lead criado: ID {$lead['id']}";
} else {
 echo "Erro {$status}: {$response}";
}

Node.js

const axios = require('axios');

async function createLead {
 try {
 const response = await axios.post(
 'https://app.syncro.chat/api/v1/leads',
 {
 name: 'João Silva',
 phone: '+5511987654321',
 email: '[email protected]',
 pipeline_id: 1,
 stage_id: 5,
 tags: ['prospect'],
 source: 'site-form',
 },
 {
 headers: {
 'X-API-Key': 'crm_a1b2c3...',
 'Content-Type': 'application/json',
 },
 }
 );

 console.log('Lead criado:', response.data.data.id);
 } catch (error) {
 console.error('Erro:', error.response?.data || error.message);
 }
}

createLead;

Python

import requests

def create_lead:
 url = 'https://app.syncro.chat/api/v1/leads'
 headers = {
 'X-API-Key': 'crm_a1b2c3...',
 'Content-Type': 'application/json',
 }
 payload = {
 'name': 'João Silva',
 'phone': '+5511987654321',
 'email': '[email protected]',
 'pipeline_id': 1,
 'stage_id': 5,
 'tags': ['prospect'],
 'source': 'site-form',
 }

 response = requests.post(url, headers=headers, json=payload)

 if response.status_code == 201:
 lead = response.json['data']
 print(f"Lead criado: ID {lead['id']}")
 else:
 print(f"Erro {response.status_code}: {response.text}")

create_lead

Idempotência — POST /leads/upsert

Se você está chamando de um sistema que pode disparar 2x (form com retry, cron com bug), use upsert ao invés de create pra evitar duplicatas.

POST https://app.syncro.chat/api/v1/leads/upsert

Payload

Mesmo de POST /leads + campo match_by:

{
 "name": "João Silva",
 "phone": "+5511987654321",
 "email": "[email protected]",
 "pipeline_id": 1,
 "stage_id": 5,
 "match_by": "email_or_phone"
}

match_by opções

Valor Comportamento
email Match por e-mail apenas
phone Match por telefone apenas
email_or_phone Match por qualquer dos dois (default)

Resposta

201 Created se criou novo:

{
 "success": true,
 "created": true,
 "data": {... }
}

200 OK se atualizou existente:

{
 "success": true,
 "created": false,
 "data": {... }
}

💡 Dica: idempotência elimina duplicatas mas sobrescreve campos do lead existente. Use com cuidado se cliente foi atualizado manualmente.

Custom fields

Pré-requisito

Crie custom fields em /configuracoes/campos-extras antes. Veja Campos personalizados.

Listar definições disponíveis

curl "https://app.syncro.chat/api/v1/custom-fields" \
 -H "X-API-Key: crm_..."

Resposta lista cada custom field com name e field_type.

Preencher na criação

{
 "name": "Maria Silva",
 "pipeline_id": 1,
 "stage_id": 5,
 "custom_fields": {
 "porte_empresa": "pequena",
 "setor": "Saúde",
 "receita_anual": 100000,
 "data_aniversario": "1990-05-15",
 "interessado": true
 }
}

Tipos suportados

field_type Formato no JSON
text, textarea string
number, currency number
date ISO string "YYYY-MM-DD"
checkbox boolean
multiselect array de strings

Tags

Tags são criadas automaticamente se não existem. Não precisa cadastrar antes.

{
 "tags": ["urgente", "vip", "indicacao-joao"]
}

Veja Tags de contatos.

UTM tracking

Sistema preenche lead.utm_* automaticamente. Aparecem em Relatório UTM.

{
 "utm_source": "instagram",
 "utm_medium": "social",
 "utm_campaign": "lancamento-2026",
 "utm_term": "crm-vendas",
 "utm_content": "carrossel-3",
 "fbclid": "IwAR0xyz",
 "gclid": "abc123def456"
}

Atribuição automática

Pra atribuir lead a usuário específico:

{
 "assigned_to": 3
}

3 é o ID do user. Pra encontrar IDs, use admin → /configuracoes/usuarios.

Sem assigned_to, lead fica sem responsável (departamento ainda pode aplicar via round-robin se configurado).

Disparar webhook após criação

Se você tem WebhookSubscription ativa com evento lead.created, ele dispara automaticamente após POST /leads retornar 201.

Veja Webhooks de saída.

Boas práticas

1. Use upsert sempre que possível

Idempotência protege contra duplicatas em retries.

2. Sanitize input antes de enviar

Validação ocorre no servidor, mas erros 422 desperdiçam requests. Valide no client primeiro.

3. Tags consistentes

vipVIPVip no Syncro (case-sensitive). Padronize lowercase no seu lado.

4. Phone em E.164

+5511987654321 (com + e DDI). Sistema normaliza, mas formato consistente facilita debug.

5. Logue response

Salve lead.id retornado em seu sistema pra referência cruzada futura.

Cenários práticos

Form externo no site

User preenche form WordPress → plugin/script faz POST.

POST /api/v1/leads
{
 "name": "{nome do form}",
 "email": "{email do form}",
 "phone": "{telefone do form}",
 "pipeline_id": 1,
 "stage_id": 5,
 "source": "wordpress-contato",
 "utm_source": "{utm da URL}"
}

Importação batch

Migração de outro CRM. Loop em CSV → POST por linha.

import csv
import requests

with open('clientes.csv') as f:
 reader = csv.DictReader(f)
 for row in reader:
 requests.post(
 'https://app.syncro.chat/api/v1/leads/upsert',
 headers={'X-API-Key': 'crm_...'},
 json={
 'name': row['nome'],
 'email': row['email'],
 'phone': row['telefone'],
 'pipeline_id': 1,
 'stage_id': 5,
 'source': 'migracao-crm-antigo',
 'match_by': 'email',
 }
 )

💡 Dica: respeite rate limit (60 req/min). Adicione time.sleep(1) entre requests.

Lead Ads custom

Se você usa Lead Ads mas não pelo Syncro nativo, pode receber webhook próprio + chamar /leads/upsert.

Webhook de e-commerce

Cliente compra → webhook do Shopify dispara seu endpoint → você cria lead no Syncro.

Erros comuns

"Phone or email is required"

Sistema exige pelo menos um. Adicione algum.

"Stage_id does not belong to the pipeline_id"

Etapa não pertence ao pipeline informado. Confira GET /pipelines.

"Tag exceeds max length"

Tags têm limite de 50 chars cada. Reduza.

"Custom field 'X' not found"

Custom field X não existe ou está inativo. Crie em /configuracoes/campos-extras ou ative.

"Plan limit reached: max_leads"

Tenant atingiu limite de leads do plano. Faça upgrade ou exclua leads antigos.

Próximos passos

Artigos relacionados