API REST para envio de mensagens WhatsApp Business, templates Meta, RCS, gestão de leads, formulários públicos de captação e webhooks assinados. SDR com IA — qualifique prospects e automatize conversas via API com exemplos em cURL, PHP, Python e Node.js.
A autenticação usa uma API Key no formato sk_live_..., gerada no painel do SDRBOT.ai. Envie a chave no header Authorization como Bearer token ou, alternativamente, no header X-API-Key. Os formulários públicos (seção Captação) são a única exceção — dispensam autenticação.
https://sdrbot.ai/api/v1
Authorization: Bearer sk_live_xxxxxxxxxxxxx
Ou, de forma equivalente:
X-API-Key: sk_live_xxxxxxxxxxxxx
| Codigo HTTP | Descrição |
|---|---|
200 |
Sucesso |
201 |
Recurso criado com sucesso |
204 |
Sucesso sem corpo na resposta (exclusao) |
400 |
Requisicao inválida (parâmetros faltando ou incorretos) |
401 |
Nao autorizado (token invalido ou ausente) |
403 |
Proibido (sem permissao para o recurso) |
404 |
Recurso nao encontrado |
409 |
Conflito (recurso duplicado) |
422 |
Entidade nao processavel (validacao falhou) |
429 |
Rate limit excedido |
500 |
Erro interno do servidor |
{
"error": {
"code": "validation_error",
"message": "The given data was invalid.",
"details": {
"campo": ["Mensagem de validacao"]
}
}
}
O campo code identifica o erro de forma estavel (ex: validation_error, lead_exists, missing_template_variables, rate_limit_exceeded) — use-o para tratamento programatico em vez da mensagem.
| Limite | Valor |
|---|---|
| Requisicoes por minuto | 60 |
| Requisicoes por dia | 10.000 |
Cada resposta inclui os headers X-RateLimit-Limit e X-RateLimit-Remaining para acompanhamento do consumo. Quando o rate limit e excedido, a API retorna 429 Too Many Requests com o header Retry-After indicando quantos segundos aguardar.
Retorna a lista paginada de leads.
| Parâmetro | Tipo | Descrição |
|---|---|---|
page |
int | Numero da pagina (default: 1) |
per_page |
int | Itens por pagina (default: 25, max: 100) |
phone |
string | Filtrar por telefone |
email |
string | Filtrar por email |
temperature |
string | Filtrar por temperatura: hot, warm, cool, cold, frozen |
sort |
string | Campo de ordenacao; prefixe com - para ordem decrescente (ex: -created_at) |
curl -X GET "https://sdrbot.ai/api/v1/leads?page=1&per_page=25&temperature=hot" \
-H "Authorization: Bearer SEU_TOKEN_AQUI" \
-H "Accept: application/json"
import requests
url = "https://sdrbot.ai/api/v1/leads"
headers = {
"Authorization": "Bearer SEU_TOKEN_AQUI",
"Accept": "application/json"
}
params = {
"page": 1,
"per_page": 25,
"temperature": "hot"
}
response = requests.get(url, headers=headers, params=params)
data = response.json()
print(data)
const response = await fetch('https://sdrbot.ai/api/v1/leads?page=1&per_page=25&temperature=hot', {
method: 'GET',
headers: {
'Authorization': 'Bearer SEU_TOKEN_AQUI',
'Accept': 'application/json'
}
});
const data = await response.json();
console.log(data);
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://sdrbot.ai/api/v1/leads?page=1&per_page=25&temperature=hot');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Authorization: Bearer SEU_TOKEN_AQUI',
'Accept: application/json'
]);
$response = curl_exec($ch);
curl_close($ch);
$data = json_decode($response, true);
print_r($data);
?>
using var client = new HttpClient();
client.DefaultRequestHeaders.Add("Authorization", "Bearer SEU_TOKEN_AQUI");
client.DefaultRequestHeaders.Add("Accept", "application/json");
var response = await client.GetAsync("https://sdrbot.ai/api/v1/leads?page=1&per_page=25&temperature=hot");
var content = await response.Content.ReadAsStringAsync();
Console.WriteLine(content);
{
"data": [
{
"id": 1234,
"name": "Joao Silva",
"email": "joao@empresa.com",
"phone": "5551999999999",
"company_name": "Empresa LTDA",
"temperature": "hot",
"lead_score": 85,
"created_at": "2026-01-10T14:30:00Z",
"updated_at": "2026-01-15T09:20:00Z"
}
],
"meta": {
"current_page": 1,
"per_page": 25,
"total": 150,
"total_pages": 6
}
}
| Parâmetro | Tipo | Obrigatório | Descrição |
|---|---|---|---|
phone |
string | Sim | Telefone com DDD e código do pais (ex: 5551999999999) — normalizado automaticamente |
name |
string | Nao | Nome do contato |
email |
string | Nao | Email do contato |
company_name |
string | Nao | Nome da empresa |
deal_value |
number | Nao | Valor estimado do negocio |
curl -X POST "https://sdrbot.ai/api/v1/leads" \
-H "Authorization: Bearer SEU_TOKEN_AQUI" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{
"phone": "5551888888888",
"name": "Maria Santos",
"email": "maria@empresa.com",
"company_name": "Tech Solutions",
"deal_value": 15000
}'
import requests
url = "https://sdrbot.ai/api/v1/leads"
headers = {
"Authorization": "Bearer SEU_TOKEN_AQUI",
"Content-Type": "application/json",
"Accept": "application/json"
}
payload = {
"phone": "5551888888888",
"name": "Maria Santos",
"email": "maria@empresa.com",
"company_name": "Tech Solutions",
"deal_value": 15000
}
response = requests.post(url, json=payload, headers=headers)
print(response.json())
const response = await fetch('https://sdrbot.ai/api/v1/leads', {
method: 'POST',
headers: {
'Authorization': 'Bearer SEU_TOKEN_AQUI',
'Content-Type': 'application/json',
'Accept': 'application/json'
},
body: JSON.stringify({
phone: '5551888888888',
name: 'Maria Santos',
email: 'maria@empresa.com',
company_name: 'Tech Solutions',
deal_value: 15000
})
});
const data = await response.json();
console.log(data);
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://sdrbot.ai/api/v1/leads');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Authorization: Bearer SEU_TOKEN_AQUI',
'Content-Type: application/json',
'Accept: application/json'
]);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode([
'phone' => '5551888888888',
'name' => 'Maria Santos',
'email' => 'maria@empresa.com',
'company_name' => 'Tech Solutions',
'deal_value' => 15000
]));
$response = curl_exec($ch);
curl_close($ch);
$data = json_decode($response, true);
print_r($data);
?>
using var client = new HttpClient();
client.DefaultRequestHeaders.Add("Authorization", "Bearer SEU_TOKEN_AQUI");
client.DefaultRequestHeaders.Add("Accept", "application/json");
var payload = new {
phone = "5551888888888",
name = "Maria Santos",
email = "maria@empresa.com",
company_name = "Tech Solutions",
deal_value = 15000
};
var json = System.Text.Json.JsonSerializer.Serialize(payload);
var content = new StringContent(json, System.Text.Encoding.UTF8, "application/json");
var response = await client.PostAsync("https://sdrbot.ai/api/v1/leads", content);
var result = await response.Content.ReadAsStringAsync();
Console.WriteLine(result);
{
"id": 1235,
"phone": "5551888888888",
"name": "Maria Santos",
"email": "maria@empresa.com",
"company_name": "Tech Solutions",
"deal_value": 15000
}
{
"error": {
"code": "validation_error",
"message": "The given data was invalid.",
"details": {
"phone": ["Resource already exists"]
}
}
}
Cada telefone e unico por conta. Para atualizar um lead existente, use o PUT /api/v1/leads/{id}.
Retorna os dados de um lead especifico pelo seu ID.
curl -X GET "https://sdrbot.ai/api/v1/leads/1234" \
-H "Authorization: Bearer SEU_TOKEN_AQUI" \
-H "Accept: application/json"
import requests
url = "https://sdrbot.ai/api/v1/leads/1234"
headers = {
"Authorization": "Bearer SEU_TOKEN_AQUI",
"Accept": "application/json"
}
response = requests.get(url, headers=headers)
data = response.json()
print(data)
const response = await fetch('https://sdrbot.ai/api/v1/leads/1234', {
method: 'GET',
headers: {
'Authorization': 'Bearer SEU_TOKEN_AQUI',
'Accept': 'application/json'
}
});
const data = await response.json();
console.log(data);
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://sdrbot.ai/api/v1/leads/1234');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Authorization: Bearer SEU_TOKEN_AQUI',
'Accept: application/json'
]);
$response = curl_exec($ch);
curl_close($ch);
$data = json_decode($response, true);
print_r($data);
?>
using var client = new HttpClient();
client.DefaultRequestHeaders.Add("Authorization", "Bearer SEU_TOKEN_AQUI");
client.DefaultRequestHeaders.Add("Accept", "application/json");
var response = await client.GetAsync("https://sdrbot.ai/api/v1/leads/1234");
var content = await response.Content.ReadAsStringAsync();
Console.WriteLine(content);
{
"data": {
"id": 1234,
"name": "Joao Silva",
"email": "joao@empresa.com",
"phone": "5551999999999",
"company_name": "Empresa LTDA",
"temperature": "hot",
"lead_score": 85,
"created_at": "2026-01-10T14:30:00Z",
"updated_at": "2026-01-15T09:20:00Z"
}
}
Aceita os mesmos campos do POST (phone, name, email, company_name, deal_value), todos opcionais. Apenas os campos enviados serao atualizados.
curl -X PUT "https://sdrbot.ai/api/v1/leads/1234" \
-H "Authorization: Bearer SEU_TOKEN_AQUI" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{
"company_name": "Empresa LTDA",
"deal_value": 50000
}'
import requests
url = "https://sdrbot.ai/api/v1/leads/1234"
headers = {
"Authorization": "Bearer SEU_TOKEN_AQUI",
"Content-Type": "application/json",
"Accept": "application/json"
}
payload = {
"company_name": "Empresa LTDA",
"deal_value": 50000
}
response = requests.put(url, json=payload, headers=headers)
print(response.json())
const response = await fetch('https://sdrbot.ai/api/v1/leads/1234', {
method: 'PUT',
headers: {
'Authorization': 'Bearer SEU_TOKEN_AQUI',
'Content-Type': 'application/json',
'Accept': 'application/json'
},
body: JSON.stringify({
company_name: 'Empresa LTDA',
deal_value: 50000
})
});
const data = await response.json();
console.log(data);
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://sdrbot.ai/api/v1/leads/1234');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT');
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Authorization: Bearer SEU_TOKEN_AQUI',
'Content-Type: application/json',
'Accept: application/json'
]);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode([
'company_name' => 'Empresa LTDA',
'deal_value' => 50000
]));
$response = curl_exec($ch);
curl_close($ch);
print_r(json_decode($response, true));
?>
using var client = new HttpClient();
client.DefaultRequestHeaders.Add("Authorization", "Bearer SEU_TOKEN_AQUI");
client.DefaultRequestHeaders.Add("Accept", "application/json");
var payload = new {
company_name = "Empresa LTDA",
deal_value = 50000
};
var json = System.Text.Json.JsonSerializer.Serialize(payload);
var content = new StringContent(json, System.Text.Encoding.UTF8, "application/json");
var response = await client.PutAsync("https://sdrbot.ai/api/v1/leads/1234", content);
var result = await response.Content.ReadAsStringAsync();
Console.WriteLine(result);
{
"data": {
"id": 1234,
"name": "Joao Silva",
"email": "joao@empresa.com",
"phone": "5551999999999",
"company_name": "Empresa LTDA",
"temperature": "hot",
"lead_score": 85,
"deal_value": 50000,
"created_at": "2026-01-10T14:30:00Z",
"updated_at": "2026-08-11T10:15:00Z"
}
}
curl -X DELETE "https://sdrbot.ai/api/v1/leads/1234" \
-H "Authorization: Bearer SEU_TOKEN_AQUI" \
-H "Accept: application/json"
import requests
url = "https://sdrbot.ai/api/v1/leads/1234"
headers = {
"Authorization": "Bearer SEU_TOKEN_AQUI",
"Accept": "application/json"
}
response = requests.delete(url, headers=headers)
print(response.status_code) # 204
const response = await fetch('https://sdrbot.ai/api/v1/leads/1234', {
method: 'DELETE',
headers: {
'Authorization': 'Bearer SEU_TOKEN_AQUI',
'Accept': 'application/json'
}
});
console.log(response.status); // 204
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://sdrbot.ai/api/v1/leads/1234');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'DELETE');
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Authorization: Bearer SEU_TOKEN_AQUI',
'Accept: application/json'
]);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
echo $httpCode; // 204
?>
using var client = new HttpClient();
client.DefaultRequestHeaders.Add("Authorization", "Bearer SEU_TOKEN_AQUI");
client.DefaultRequestHeaders.Add("Accept", "application/json");
var response = await client.DeleteAsync("https://sdrbot.ai/api/v1/leads/1234");
Console.WriteLine(response.StatusCode); // NoContent (204)
Retorna status 204 sem corpo na resposta.
Envia mensagens via WhatsApp Business API. Suporta texto livre, templates pre-aprovados pela Meta e midia (imagem, video, documento e audio). Importante: fora da janela de 24 horas de atendimento, a Meta exige template aprovado — texto livre e midia só chegam em conversas ativas.
| Parâmetro | Tipo | Obrigatório | Descrição |
|---|---|---|---|
integration_id |
int | Sim | ID do canal (integração) WhatsApp que fara o envio |
type |
string | Sim | Tipo: text, template, image, video, document, audio |
phone / lead_id / whatsapp_user_id |
string / int / string | Um deles | Destinatario: telefone com código do pais (ex: 5551999999999), ID do lead ou ID do usuario WhatsApp |
| Tipo | Parâmetros |
|---|---|
text |
text (obrigatório) — conteudo da mensagem |
template |
template_id ou template_name (obrigatório); template_language (opcional, default do template ou pt_BR); variables — objeto nomeado ou array posicional na ordem das variaveis |
image / video / document / audio |
media_url ou media_id (obrigatório); caption (opcional); filename (obrigatório para document) |
curl -X POST "https://sdrbot.ai/api/v1/whatsapp/messages" \
-H "Authorization: Bearer sk_live_xxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"integration_id": 1,
"phone": "5551999999999",
"type": "text",
"text": "Ola Joao! Tudo bem? Gostaria de agendar uma demonstracao do nosso produto."
}'
import requests
url = "https://sdrbot.ai/api/v1/whatsapp/messages"
headers = {
"Authorization": "Bearer sk_live_xxxxxxxxxxxxx",
"Content-Type": "application/json"
}
payload = {
"integration_id": 1,
"phone": "5551999999999",
"type": "text",
"text": "Ola Joao! Tudo bem? Gostaria de agendar uma demonstracao do nosso produto."
}
response = requests.post(url, json=payload, headers=headers)
print(response.json())
const response = await fetch('https://sdrbot.ai/api/v1/whatsapp/messages', {
method: 'POST',
headers: {
'Authorization': 'Bearer sk_live_xxxxxxxxxxxxx',
'Content-Type': 'application/json'
},
body: JSON.stringify({
integration_id: 1,
phone: '5551999999999',
type: 'text',
text: 'Ola Joao! Tudo bem? Gostaria de agendar uma demonstracao do nosso produto.'
})
});
const data = await response.json();
console.log(data);
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://sdrbot.ai/api/v1/whatsapp/messages');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Authorization: Bearer sk_live_xxxxxxxxxxxxx',
'Content-Type: application/json'
]);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode([
'integration_id' => 1,
'phone' => '5551999999999',
'type' => 'text',
'text' => 'Ola Joao! Tudo bem? Gostaria de agendar uma demonstracao do nosso produto.'
]));
$response = curl_exec($ch);
curl_close($ch);
print_r(json_decode($response, true));
?>
using var client = new HttpClient();
client.DefaultRequestHeaders.Add("Authorization", "Bearer sk_live_xxxxxxxxxxxxx");
var payload = new {
integration_id = 1,
phone = "5551999999999",
type = "text",
text = "Ola Joao! Tudo bem? Gostaria de agendar uma demonstracao do nosso produto."
};
var json = System.Text.Json.JsonSerializer.Serialize(payload);
var content = new StringContent(json, System.Text.Encoding.UTF8, "application/json");
var response = await client.PostAsync("https://sdrbot.ai/api/v1/whatsapp/messages", content);
var result = await response.Content.ReadAsStringAsync();
Console.WriteLine(result);
Templates precisam de aprovacao previa da Meta. O campo variables aceita objeto nomeado (recomendado) ou array posicional na ordem das variaveis do template. Se faltar variavel obrigatoria, a API retorna o erro missing_template_variables listando os campos ausentes.
curl -X POST "https://sdrbot.ai/api/v1/whatsapp/messages" \
-H "Authorization: Bearer sk_live_xxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"integration_id": 1,
"lead_id": 1234,
"type": "template",
"template_id": 42,
"variables": { "nome": "Joao", "empresa": "Empresa LTDA" }
}'
curl -X POST "https://sdrbot.ai/api/v1/whatsapp/messages" \
-H "Authorization: Bearer sk_live_xxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"integration_id": 1,
"phone": "5551999999999",
"type": "image",
"media_url": "https://seusite.com.br/img/proposta-comercial.png",
"caption": "Confira nossa proposta comercial personalizada!"
}'
curl -X POST "https://sdrbot.ai/api/v1/whatsapp/messages" \
-H "Authorization: Bearer sk_live_xxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"integration_id": 1,
"lead_id": 1234,
"type": "document",
"media_url": "https://seusite.com.br/docs/proposta.pdf",
"filename": "proposta-comercial.pdf"
}'
{
"id": "msg_abc123def456",
"status": "sent",
"timestamp": "2026-08-11T10:30:00Z"
}
Lista os templates HSM da integração, com variaveis, preview e status de aprovacao na Meta. Use o id retornado como template_id no envio.
| Parâmetro | Tipo | Descrição |
|---|---|---|
integration_id |
int | Obrigatório — ID do canal WhatsApp |
category |
string | Filtrar por categoria |
context |
string | Filtrar por contexto |
meta_approved_only |
boolean | Somente templates aprovados pela Meta (true/false) |
curl -X GET "https://sdrbot.ai/api/v1/whatsapp/templates?integration_id=1&meta_approved_only=true" \
-H "Authorization: Bearer sk_live_xxxxxxxxxxxxx" \
-H "Accept: application/json"
{
"data": [
{
"id": 42,
"integration_id": 1,
"name": "Boas Vindas",
"meta_template_name": "boas_vindas",
"description": "Mensagem de abertura para novos leads",
"category": "Warming",
"variables": ["nome", "empresa"],
"preview": "Ola Joao, bem-vindo! Vi que a Empresa LTDA conheceu nosso produto...",
"language": "pt_BR",
"status": "approved",
"stats": {
"usage_count": 128,
"success_rate": "98.40"
}
}
]
}
Envia mensagens via RCS (Rich Communication Services). Suporta texto, arquivo, cards ricos, carousels, texto com sugestoes de resposta e localizacao.
| Parâmetro | Tipo | Obrigatório | Descrição |
|---|---|---|---|
type |
string | Sim | Tipo: text, file, card, carousel, replyable_text, location |
phone / lead_id |
string / int | Um deles | Destinatario: telefone com código do pais ou ID do lead |
Ate 4.096 caracteres.
curl -X POST "https://sdrbot.ai/api/v1/rcs/messages" \
-H "Authorization: Bearer sk_live_xxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"phone": "5551999999999",
"type": "text",
"text": "Ola! Obrigado pelo seu interesse. Como posso ajudar?"
}'
Imagem, video ou documento via URL publica, com o mime_type correspondente.
curl -X POST "https://sdrbot.ai/api/v1/rcs/messages" \
-H "Authorization: Bearer sk_live_xxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"lead_id": 1234,
"type": "file",
"file_url": "https://seusite.com.br/docs/catalogo.pdf",
"mime_type": "application/pdf"
}'
Titulo de ate 200 caracteres e ate 4 botoes de acao (url, call, reply).
curl -X POST "https://sdrbot.ai/api/v1/rcs/messages" \
-H "Authorization: Bearer sk_live_xxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"phone": "5551999999999",
"type": "card",
"title": "Plano Empresarial",
"description": "Ideal para empresas com mais de 50 colaboradores. Inclui suporte prioritario e integração completa.",
"media_url": "https://seusite.com.br/img/plano-empresarial.jpg",
"buttons": [
{
"type": "url",
"text": "Ver detalhes",
"url": "https://seusite.com.br/planos/empresarial"
},
{
"type": "reply",
"text": "Quero contratar",
"payload": "contratar_empresarial"
}
]
}'
De 2 a 10 cards; card_width aceita SMALL ou MEDIUM (default).
curl -X POST "https://sdrbot.ai/api/v1/rcs/messages" \
-H "Authorization: Bearer sk_live_xxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"phone": "5551999999999",
"type": "carousel",
"card_width": "MEDIUM",
"cards": [
{
"title": "Plano Starter",
"description": "Para pequenas empresas. Ate 10 usuarios.",
"media_url": "https://seusite.com.br/img/plano-starter.jpg",
"buttons": [
{ "type": "reply", "text": "Saber mais", "payload": "info_starter" }
]
},
{
"title": "Plano Business",
"description": "Para empresas em crescimento. Ate 50 usuarios.",
"media_url": "https://seusite.com.br/img/plano-business.jpg",
"buttons": [
{ "type": "reply", "text": "Saber mais", "payload": "info_business" }
]
}
]
}'
Ate 11 sugestoes de resposta rapida, cada uma com text e payload.
curl -X POST "https://sdrbot.ai/api/v1/rcs/messages" \
-H "Authorization: Bearer sk_live_xxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"phone": "5551999999999",
"type": "replyable_text",
"text": "Qual horario funciona melhor para uma demonstracao?",
"quick_replies": [
{ "text": "Manha (9h-12h)", "payload": "horario_manha" },
{ "text": "Tarde (14h-17h)", "payload": "horario_tarde" },
{ "text": "Noite (18h-20h)", "payload": "horario_noite" }
]
}'
curl -X POST "https://sdrbot.ai/api/v1/rcs/messages" \
-H "Authorization: Bearer sk_live_xxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"lead_id": 1234,
"type": "location",
"latitude": -30.0346,
"longitude": -51.2177,
"label": "IAGENTE - Escritorio Porto Alegre"
}'
{
"id": "rcs_xyz789abc123",
"status": "sent",
"timestamp": "2026-08-11T11:00:00Z"
}
Capture leads de formularios do seu site direto na pipeline, sem backend e sem expor sua API Key: a autenticação e feita por um token opaco (frm_...) na propria URL, gerado no painel ao criar o formulario. Cada formulario tem configuracao propria de dominios permitidos (CORS), honeypot, rate limit por IP e assinatura HMAC opcional.
Aceita application/json, application/x-www-form-urlencoded e multipart/form-data — funciona com um <form> HTML puro ou via fetch.
| Campo | Obrigatório | Descrição |
|---|---|---|
phone |
Sim | Telefone do lead — normalizado automaticamente |
name, email, company_name, role |
Nao | Dados do contato |
utm_source, utm_medium, utm_campaign, utm_term, utm_content |
Nao | Parâmetros de atribuicao de campanha |
| Campos mapeados | Nao | Campos personalizados configurados no formulario (painel) |
curl -X POST "https://sdrbot.ai/api/forms/frm_SEU_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "Maria Santos",
"phone": "5551999999999",
"email": "maria@empresa.com",
"utm_source": "google",
"utm_medium": "cpc",
"utm_campaign": "institucional"
}'
{
"success": true,
"lead_id": 123,
"submission_id": 456,
"duplicate": false
}
Se o telefone ja existir na conta, o lead e atualizado e duplicate retorna true. Envios que caem no honeypot tambem retornam 200 (silenciosamente descartados).
| Codigo | Erro | Significado |
|---|---|---|
200 |
— | Lead criado/atualizado (inclusive honeypot silencioso) |
401 |
invalid_signature |
Assinatura HMAC nao confere |
403 |
origin_not_allowed |
Dominio fora da lista de origens permitidas |
404 |
form_not_found |
Token invalido ou formulario pausado |
422 |
validation_error |
Campo obrigatório phone ausente |
429 |
rate_limit_exceeded |
Limite por IP ou por conta atingido |
Se o formulario tiver um webhook_secret configurado, envie o header X-Signature com o HMAC-SHA256 do corpo bruto:
SECRET="seu_secret"
BODY='{"phone":"5551999999999"}'
SIG=$(echo -n "$BODY" | openssl dgst -sha256 -hmac "$SECRET" | awk '{print $2}')
curl -X POST "https://sdrbot.ai/api/forms/frm_SEU_TOKEN" \
-H "X-Signature: sha256=$SIG" \
-H "Content-Type: application/json" \
-d "$BODY"
Valida o token sem criar lead — retorna 200 se o formulario esta ativo. Util para monitorar a integração.
| Parâmetro | Tipo | Obrigatório | Descrição |
|---|---|---|---|
name |
string | Sim | Nome de identificacao do webhook |
url |
string | Sim | URL de callback (HTTPS) |
events |
array | Sim | Lista de eventos para escutar (ver tabela abaixo) |
curl -X POST "https://sdrbot.ai/api/v1/webhooks" \
-H "Authorization: Bearer sk_live_xxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"name": "CRM Interno",
"url": "https://seusite.com.br/webhooks/sdrbot",
"events": ["lead.created", "lead.qualified", "message.received"]
}'
{
"id": 5,
"name": "CRM Interno",
"url": "https://seusite.com.br/webhooks/sdrbot",
"events": ["lead.created", "lead.qualified", "message.received"],
"signing_secret": "whsec_a1b2c3d4e5f6..."
}
Guarde o signing_secret com segurança — ele e usado para validar a assinatura das entregas (ver Verificacao de Assinatura).
curl -X GET "https://sdrbot.ai/api/v1/webhooks" \
-H "Authorization: Bearer sk_live_xxxxxxxxxxxxx" \
-H "Accept: application/json"
Envia um evento de teste para a URL configurada — valide a entrega e a assinatura antes de ir para produção.
curl -X POST "https://sdrbot.ai/api/v1/webhooks/5/test" \
-H "Authorization: Bearer sk_live_xxxxxxxxxxxxx" \
-H "Accept: application/json"
| Evento | Descrição |
|---|---|
lead.created |
Novo lead criado |
lead.updated |
Lead atualizado |
lead.qualified |
Lead qualificado pela IA |
message.received |
Mensagem recebida do lead |
message.sent |
Mensagem enviada ao lead |
handoff.created |
Atendimento transferido para humano |
handoff.closed |
Atendimento humano encerrado |
POST https://seusite.com.br/webhooks/sdrbot
Headers:
Content-Type: application/json
X-Webhook-Signature: sha256=abc123def456...
Body:
{
"id": "evt_789xyz",
"event": "lead.qualified",
"timestamp": "2026-08-11T10:30:00Z",
"data": {
"lead_id": 1234,
"phone": "5551999999999",
"name": "Joao Silva",
"email": "joao@empresa.com",
"company_name": "Empresa LTDA"
}
}
Cada entrega inclui o header X-Webhook-Signature no formato sha256=<hex> — o HMAC-SHA256 do corpo bruto da requisição, calculado com o signing_secret retornado na criacao do webhook. Sempre valide antes de processar, usando comparacao de tempo constante.
<?php
$secret = 'whsec_seu_signing_secret';
$payload = file_get_contents('php://input');
$signature = $_SERVER['HTTP_X_WEBHOOK_SIGNATURE'] ?? '';
$expected = 'sha256=' . hash_hmac('sha256', $payload, $secret);
if (!hash_equals($expected, $signature)) {
http_response_code(401);
echo json_encode(['error' => 'Assinatura invalida']);
exit;
}
// Assinatura válida - processar o webhook
$evento = json_decode($payload, true);
switch ($evento['event']) {
case 'lead.created':
// Processar novo lead
break;
case 'lead.qualified':
// Processar lead qualificado
break;
case 'message.received':
// Processar mensagem recebida
break;
}
http_response_code(200);
echo json_encode(['ok' => true]);
?>
import hmac
import hashlib
import json
from flask import Flask, request, jsonify
app = Flask(__name__)
SECRET = 'whsec_seu_signing_secret'
@app.route('/webhooks/sdrbot', methods=['POST'])
def handle_webhook():
payload = request.get_data()
signature = request.headers.get('X-Webhook-Signature', '')
expected = 'sha256=' + hmac.new(
SECRET.encode(),
payload,
hashlib.sha256
).hexdigest()
if not hmac.compare_digest(expected, signature):
return jsonify({'error': 'Assinatura invalida'}), 401
evento = json.loads(payload)
if evento['event'] == 'lead.created':
# Processar novo lead
pass
elif evento['event'] == 'lead.qualified':
# Processar lead qualificado
pass
elif evento['event'] == 'message.received':
# Processar mensagem recebida
pass
return jsonify({'ok': True}), 200
const crypto = require('crypto');
const express = require('express');
const app = express();
const SECRET = 'whsec_seu_signing_secret';
app.post('/webhooks/sdrbot', express.raw({ type: 'application/json' }), (req, res) => {
const payload = req.body;
const signature = req.headers['x-webhook-signature'] || '';
const expected = 'sha256=' + crypto
.createHmac('sha256', SECRET)
.update(payload)
.digest('hex');
if (!crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(signature))) {
return res.status(401).json({ error: 'Assinatura invalida' });
}
const evento = JSON.parse(payload);
switch (evento.event) {
case 'lead.created':
// Processar novo lead
break;
case 'lead.qualified':
// Processar lead qualificado
break;
case 'message.received':
// Processar mensagem recebida
break;
}
res.json({ ok: true });
});
using System.Security.Cryptography;
using System.Text;
using System.Text.Json;
using Microsoft.AspNetCore.Mvc;
[ApiController]
[Route("webhooks/sdrbot")]
public class SdrbotWebhookController : ControllerBase
{
private const string Secret = "whsec_seu_signing_secret";
[HttpPost]
public IActionResult HandleWebhook()
{
using var reader = new StreamReader(Request.Body);
var payload = reader.ReadToEndAsync().Result;
var signature = Request.Headers["X-Webhook-Signature"].ToString();
using var hmac = new HMACSHA256(Encoding.UTF8.GetBytes(Secret));
var hash = hmac.ComputeHash(Encoding.UTF8.GetBytes(payload));
var expected = "sha256=" + BitConverter.ToString(hash).Replace("-", "").ToLower();
if (!CryptographicOperations.FixedTimeEquals(
Encoding.UTF8.GetBytes(expected),
Encoding.UTF8.GetBytes(signature)))
{
return Unauthorized(new { error = "Assinatura invalida" });
}
var evento = JsonDocument.Parse(payload).RootElement;
var eventType = evento.GetProperty("event").GetString();
switch (eventType)
{
case "lead.created":
// Processar novo lead
break;
case "lead.qualified":
// Processar lead qualificado
break;
case "message.received":
// Processar mensagem recebida
break;
}
return Ok(new { ok = true });
}
}
Precisa de ajuda? Entre em contato com nosso suporte tecnico pelo WhatsApp ou acesse a Central de Ajuda.