Referencia de API REST
Descripción General
LeadHub incluye una API REST completa que permite a herramientas externas leer y escribir tus datos: leads, pipelines, automatizaciones, formularios y más. Úsala para integrarte con Zapier, crear dashboards personalizados, conectar tu sitio web o automatizar cualquier cosa.
URL Base
Todas las peticiones de la API van a:
https://yourdomain.com/api/v1
Reemplaza yourdomain.com con tu dominio real de LeadHub.
Autenticación
Cada petición (excepto el health check) requiere una clave de API.
Crea claves de API en el panel de administración en Ajustes → Claves de API. Consulta la página de Ajustes para instrucciones.
Incluye tu clave de API en cada petición como token Bearer en la cabecera Authorization:
Authorization: Bearer lh_your_api_key_here
Si envías una petición sin clave de API, o con una clave inválida, recibirás una respuesta 401 Unauthorized.
Limitación de Velocidad
Cada clave de API está limitada a 1.000 peticiones por hora por defecto (configurable por clave). Si superas este límite, recibirás una respuesta 429 Too Many Requests.
Cada respuesta incluye estas cabeceras para que puedas controlar tu uso:
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 847
X-RateLimit-Reset: 1711580400
X-RateLimit-Reset es un timestamp Unix de cuándo se reinicia tu límite.
Paginación
Los endpoints que devuelven listas de registros admiten paginación. Añade estos parámetros de consulta:
| Parámetro | Por defecto | Máximo |
|---|---|---|
page | 1 | — |
per_page | 15 | 100 |
Ejemplo: GET /api/v1/leads?page=2&per_page=25
Formato de Respuesta
Respuesta Exitosa
{
"data": { ... },
"meta": {
"current_page": 1,
"last_page": 5,
"per_page": 15,
"total": 73,
"from": 1,
"to": 15
},
"links": {
"first": "https://yourdomain.com/api/v1/leads?page=1",
"last": "https://yourdomain.com/api/v1/leads?page=5",
"prev": null,
"next": "https://yourdomain.com/api/v1/leads?page=2",
"self": "https://yourdomain.com/api/v1/leads?page=1"
}
}
Para respuestas de un solo registro (show, create, update), data contiene el objeto del registro y meta se omite.
Respuesta de Error
{
"status": "error",
"message": "The given data was invalid.",
"code": "VALIDATION_FAILED",
"errors": {
"email": ["The email field must be a valid email address."]
}
}
Códigos de error comunes:
| Código | Estado HTTP | Significado |
|---|---|---|
UNAUTHORIZED | 401 | Clave de API ausente o inválida |
FORBIDDEN | 403 | La clave de API carece del alcance requerido |
NOT_FOUND | 404 | El registro no existe |
VALIDATION_FAILED | 422 | Los datos de la petición fallaron la validación |
RATE_LIMITED | 429 | Demasiadas peticiones |
SERVER_ERROR | 500 | Error inesperado del servidor |
Health Check
No requiere autenticación.
GET /api/v1/health
Respuesta:
{
"status": "ok",
"version": "1.0.0",
"timestamp": "2026-03-28T09:15:00+00:00"
}
Úsalo para verificar si tu instancia de LeadHub es accesible antes de hacer otras peticiones.
Leads
Alcance requerido: read:leads para recuperar, write:leads para crear/actualizar, delete:leads para eliminar.
Listar Leads
GET /api/v1/leads
Parámetros de consulta para filtrar:
| Parámetro | Descripción |
|---|---|
source | Filtrar por fuente (p. ej. facebook, website) |
status | Filtrar por estado (p. ej. new, contacted, qualified) |
pipeline_id | Filtrar por ID de pipeline |
stage_id | Filtrar por ID de etapa del pipeline |
assigned_user_id | Filtrar por ID de usuario asignado |
tag | Filtrar por nombre de etiqueta |
search | Buscar por nombre, email o teléfono |
created_after | Fecha ISO 8601 — solo leads creados después de esta fecha |
created_before | Fecha ISO 8601 — solo leads creados antes de esta fecha |
starred | true para mostrar solo leads destacados |
sort | Campo para ordenar: created_at, updated_at, lead_score, first_name, last_name, email |
direction | asc o desc (por defecto: desc) |
Obtener un Lead
GET /api/v1/leads/{id}
Crear un Lead
POST /api/v1/leads
Cuerpo de la petición (JSON):
{
"first_name": "Sarah",
"last_name": "Johnson",
"email": "[email protected]",
"phone": "+14155551234",
"source": "website",
"status": "new",
"pipeline_id": 1,
"pipeline_stage_id": 2,
"assigned_user_id": 5,
"notes": "Interested in the enterprise plan.",
"custom_fields": {
"budget": "10000"
},
"tags": ["hot-lead", "enterprise"]
}
first_name es obligatorio. Todos los demás campos son opcionales.
Actualizar un Lead
PUT /api/v1/leads/{id}
PATCH /api/v1/leads/{id}
Envía solo los campos que quieras actualizar. Los mismos campos que en crear.
Eliminar un Lead
DELETE /api/v1/leads/{id}
Añadir una Etiqueta a un Lead
POST /api/v1/leads/{id}/tags
Cuerpo: { "tag": "vip-client" }
Eliminar una Etiqueta de un Lead
DELETE /api/v1/leads/{id}/tags/{tag}
Pipelines
Alcance requerido: read:pipelines o write:pipelines
GET /api/v1/pipelines
POST /api/v1/pipelines
GET /api/v1/pipelines/{id}
PUT /api/v1/pipelines/{id}
PATCH /api/v1/pipelines/{id}
DELETE /api/v1/pipelines/{id}
Etapas del Pipeline
GET /api/v1/pipelines/{pipeline_id}/stages
POST /api/v1/pipelines/{pipeline_id}/stages
GET /api/v1/pipelines/{pipeline_id}/stages/{stage_id}
PUT /api/v1/pipelines/{pipeline_id}/stages/{stage_id}
PATCH /api/v1/pipelines/{pipeline_id}/stages/{stage_id}
DELETE /api/v1/pipelines/{pipeline_id}/stages/{stage_id}
Etiquetas
Alcance requerido: read:tags o write:tags
GET /api/v1/tags
POST /api/v1/tags
GET /api/v1/tags/{id}
PUT /api/v1/tags/{id}
PATCH /api/v1/tags/{id}
DELETE /api/v1/tags/{id}
Usuarios
Alcance requerido: read:users, write:users o delete:users
GET /api/v1/users
POST /api/v1/users
GET /api/v1/users/{id}
PUT /api/v1/users/{id}
PATCH /api/v1/users/{id}
DELETE /api/v1/users/{id}
Formularios
Alcance requerido: read:forms, write:forms o delete:forms
GET /api/v1/forms
POST /api/v1/forms
GET /api/v1/forms/{id}
PUT /api/v1/forms/{id}
PATCH /api/v1/forms/{id}
DELETE /api/v1/forms/{id}
Enviar un Formulario
POST /api/v1/forms/{id}/submissions
Cuerpo: los valores de los campos del formulario como pares clave-valor.
Automatizaciones
Alcance requerido: read:automations, write:automations o delete:automations
GET /api/v1/automations
POST /api/v1/automations
GET /api/v1/automations/{id}
PUT /api/v1/automations/{id}
PATCH /api/v1/automations/{id}
DELETE /api/v1/automations/{id}
Integraciones
Alcance requerido: read:integrations o write:integrations
GET /api/v1/integrations/types
GET /api/v1/integrations
POST /api/v1/integrations
GET /api/v1/integrations/{id}
PUT /api/v1/integrations/{id}
PATCH /api/v1/integrations/{id}
DELETE /api/v1/integrations/{id}
GET /api/v1/integrations/types devuelve la lista de tipos de integración disponibles (Facebook, Google Ads, Mailgun, etc.).
Ingesta de Leads Entrantes
Un endpoint simplificado para crear leads desde fuentes externas, webhooks o herramientas sin código como Zapier y Make.
POST /api/inbound/leads?tenant={workspace-slug}
Autentícate con Authorization: Bearer {api_key} y pasa el slug del workspace como parámetro de consulta.
Cuerpo de la petición:
{
"email": "[email protected]",
"first_name": "Sarah",
"last_name": "Johnson",
"phone": "+14155551234",
"company": "Tech Corp",
"source": "zapier",
"notes": "Came from newsletter signup",
"tags": ["newsletter"],
"custom_fields": {
"utm_campaign": "spring-promo"
}
}
email es obligatorio. Todos los demás campos son opcionales.
Respuesta de éxito (201):
{
"status": "created",
"lead_id": 1842,
"is_duplicate": false
}
Si el lead ya existe (identificado por email o teléfono), is_duplicate es true y se devuelve el ID del lead existente.
Ejemplos de Código
cURL
curl -X GET "https://yourdomain.com/api/v1/leads?status=new&per_page=25" \
-H "Authorization: Bearer lh_your_api_key_here" \
-H "Accept: application/json"
curl -X POST "https://yourdomain.com/api/v1/leads" \
-H "Authorization: Bearer lh_your_api_key_here" \
-H "Content-Type: application/json" \
-d '{"first_name":"Sarah","email":"[email protected]","source":"api"}'
PHP
$apiKey = 'lh_your_api_key_here';
$baseUrl = 'https://yourdomain.com/api/v1';
// List leads
$response = file_get_contents($baseUrl . '/leads', false, stream_context_create([
'http' => [
'header' => "Authorization: Bearer {$apiKey}\r\nAccept: application/json\r\n",
],
]));
$leads = json_decode($response, true);
// Create a lead
$ch = curl_init($baseUrl . '/leads');
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"Authorization: Bearer {$apiKey}",
"Content-Type: application/json",
"Accept: application/json",
]);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode([
'first_name' => 'Sarah',
'email' => '[email protected]',
'source' => 'api',
]));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$result = json_decode(curl_exec($ch), true);
curl_close($ch);
JavaScript (fetch)
const apiKey = 'lh_your_api_key_here';
const baseUrl = 'https://yourdomain.com/api/v1';
// List leads
const response = await fetch(`${baseUrl}/leads?status=new`, {
headers: {
'Authorization': `Bearer ${apiKey}`,
'Accept': 'application/json',
},
});
const { data, meta } = await response.json();
// Create a lead
const createResponse = await fetch(`${baseUrl}/leads`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${apiKey}`,
'Content-Type': 'application/json',
'Accept': 'application/json',
},
body: JSON.stringify({
first_name: 'Sarah',
email: '[email protected]',
source: 'website',
}),
});
const newLead = await createResponse.json();