Meet the Recaudo MCP Server — 139 tools for AI agents

Documentación de la API

Guía completa para integrar Recaudo en tus aplicaciones

¿Integrando con un agente de IA?

Si usas Claude Code, Cursor, Codex, Windsurf u otro asistente de código, tenemos instrucciones listas para copiar y pegar.

Autenticación

La API de Recaudo utiliza API keys para autenticar las peticiones. Crea una cuenta para obtener tus API keys.

Importante: Nunca expongas tu Secret Key en codigo del lado del cliente. Usa la Public Key para operaciones frontend.

Tipos de API Keys

Tipo Prefijo Uso
Public Key (Live) pk_live_ Frontend, checkout forms
Secret Key (Live) sk_live_ Backend, operaciones sensibles
Public Key (Test) pk_test_ Desarrollo frontend
Secret Key (Test) sk_test_ Desarrollo backend

Autenticacion via Header

Incluye tu API key en el header Authorization como Bearer token:

curl https://recaudo.app/api/v1/customers \
  -H "Authorization: Bearer sk_live_tu_secret_key" \
  -H "Content-Type: application/json"
$client = new \GuzzleHttp\Client();

$response = $client->request('GET', 'https://recaudo.app/api/v1/customers', [
    'headers' => [
        'Authorization' => 'Bearer sk_live_tu_secret_key',
        'Content-Type' => 'application/json',
        'Accept' => 'application/json',
    ]
]);

$data = json_decode($response->getBody(), true);
const response = await fetch('https://recaudo.app/api/v1/customers', {
  method: 'GET',
  headers: {
    'Authorization': 'Bearer sk_live_tu_secret_key',
    'Content-Type': 'application/json',
  }
});

const data = await response.json();
import requests

response = requests.get(
    'https://recaudo.app/api/v1/customers',
    headers={
        'Authorization': 'Bearer sk_live_tu_secret_key',
        'Content-Type': 'application/json',
    }
)

data = response.json()

MCP Server

Integra Recaudo con asistentes de IA

Recaudo incluye un servidor MCP (Model Context Protocol) que permite a asistentes de IA como Claude Desktop, Cursor, Windsurf, Claude Code y otros clientes MCP interactuar directamente con tu cuenta: gestionar clientes, crear facturas, cobrar, enviar WhatsApp, CRM, automatizaciones y más.

Requisitos

  • Node.js 18 o superior
  • Una Secret Key de la API (sk_live_ o sk_test_)

Configuración en Claude Desktop

Edita el archivo claude_desktop_config.json (Mac: ~/Library/Application Support/Claude/claude_desktop_config.json | Windows: %APPDATA%\Claude\claude_desktop_config.json):

claude_desktop_config.json
{
  "mcpServers": {
    "recaudo": {
      "command": "npx",
      "args": ["-y", "@recaudo/mcp-server"],
      "env": {
        "RECAUDO_API_KEY": "sk_live_tu_secret_key"
      }
    }
  }
}
Reemplaza sk_live_tu_secret_key con tu Secret Key. Puedes generarla en API Keys. Reinicia Claude Desktop después de guardar la configuración.

Configuración en Claude Code

Terminal
claude mcp add recaudo -e RECAUDO_API_KEY=sk_live_tu_secret_key -- npx -y @recaudo/mcp-server

Configuración en Cursor / Windsurf

Crea el archivo .cursor/mcp.json en la raíz de tu proyecto:

.cursor/mcp.json
{
  "mcpServers": {
    "recaudo": {
      "command": "npx",
      "args": ["-y", "@recaudo/mcp-server"],
      "env": {
        "RECAUDO_API_KEY": "sk_live_tu_secret_key"
      }
    }
  }
}

Herramientas disponibles

El MCP Server expone 110 herramientas organizadas en 20 módulos:

Grupo Herramientas Descripción
Clientes 7 CRUD, métodos de pago, suscripciones
Facturas 9 CRUD, parcialidades, moratorios
Links de Pago 5 Crear, cancelar, ver pagos
Cargos 3 Cobros directos, reembolsos
Productos 10 Catálogo: categorías y productos con inventario
Pedidos 8 Crear, enviar, entregar, completar pedidos
Conversaciones 7 WhatsApp, Messenger, Instagram: mensajes y templates
Planes 3 Listar y crear planes de suscripción
Suscripciones 7 Ciclo completo: crear, pausar, cancelar
Flujos 6 Desplegar flujos conversacionales
Webhooks 4 Configurar y probar webhooks

Ejemplo de uso

Una vez configurado, puedes hablar con tu asistente de IA en lenguaje natural:

Conversación con Claude

Usuario: Lista mis clientes con suscripción activa

Claude: Encontré 24 clientes con suscripción activa...

Usuario: Crea un link de pago de $500 para Juan Pérez

Claude: Link creado: https://recaudo.app/pay/abc123...

Usuario: ¿Cuántas facturas pendientes tengo?

Claude: Tienes 12 facturas pendientes por un total de $45,300.00...

El MCP Server usa tu Secret Key para autenticarse. Todas las operaciones respetan los mismos permisos y límites que la API REST.

Guía para Agentes de IA

Instrucciones para Claude Code, Codex, Cursor, Windsurf y otros asistentes de código

Si estás delegando la integración de Recaudo a un agente de IA (Claude Code, OpenAI Codex, Cursor, Windsurf, GitHub Copilot, etc.), copia el siguiente bloque de instrucciones y pégalo en tu prompt o archivo de contexto del proyecto (CLAUDE.md, .cursorrules, AGENTS.md, etc.). El agente tendrá todo lo necesario para integrar correctamente.

CLAUDE.md / .cursorrules / AGENTS.md
# Integración con Recaudo — Guía para Agentes de IA

## Qué es Recaudo
Recaudo es una plataforma de orquestación de pagos con API REST. Permite crear links de pago,
cobrar con tarjeta, gestionar clientes, suscripciones, facturas, WhatsApp y más.

## Base URL
```
https://recaudo.app/api/v1
```

## Autenticación
Todas las peticiones requieren el header:
```
Authorization: Bearer {SECRET_KEY}
```
La Secret Key se obtiene desde el panel en Configuración → API Keys.
NUNCA exponer la Secret Key en código frontend.

## Montos
TODOS los montos son en DECIMALES (100.00 = $100 pesos). NO usar centavos.

## Endpoints principales

### Clientes
- `GET    /customers` — Listar clientes (paginado, ?search=, ?page=)
- `POST   /customers` — Crear cliente (name, email, phone?, city?, notes?)
- `GET    /customers/{id}` — Ver cliente
- `PUT    /customers/{id}` — Actualizar cliente
- `DELETE /customers/{id}` — Eliminar cliente

### Links de Pago
- `GET    /payment-links` — Listar links
- `POST   /payment-links` — Crear link (title, amount, currency?, description?, expiration_days?)
- `GET    /payment-links/{id}` — Ver link
- `PUT    /payment-links/{id}` — Actualizar link
- `DELETE /payment-links/{id}` — Eliminar link

### Cargos (cobro directo con tarjeta tokenizada)
- `POST   /charges` — Crear cargo (customer_id, amount, currency, payment_method_token, description?)
- `GET    /charges/{id}` — Ver cargo

### Tokenización (guardar tarjeta)
- `POST   /customers/{id}/payment-methods` — Tokenizar tarjeta (card_number, exp_month, exp_year, cvv, holder_name)
- `GET    /customers/{id}/payment-methods` — Listar métodos de pago
- `DELETE /customers/{id}/payment-methods/{pm_id}` — Eliminar método

### Suscripciones
- `GET    /subscriptions` — Listar suscripciones
- `POST   /subscriptions` — Crear (customer_id, plan_name, amount, currency, interval: monthly|yearly, payment_method_token?)
- `GET    /subscriptions/{id}` — Ver suscripción
- `POST   /subscriptions/{id}/cancel` — Cancelar
- `POST   /subscriptions/{id}/pause` — Pausar
- `POST   /subscriptions/{id}/resume` — Reanudar

### Facturas
- `GET    /invoices` — Listar facturas
- `POST   /invoices` — Crear factura (customer_id, items[{description, quantity, unit_price}], due_date?, notes?)
- `GET    /invoices/{id}` — Ver factura
- `POST   /invoices/{id}/send` — Enviar por email
- `POST   /invoices/{id}/mark-paid` — Marcar como pagada

### Webhooks
- `GET    /webhook-endpoints` — Listar endpoints
- `POST   /webhook-endpoints` — Crear endpoint (url, events[], description)
- `GET    /webhook-endpoints/{id}` — Ver detalle con secret
- `PUT    /webhook-endpoints/{id}` — Actualizar url, eventos, estado
- `DELETE /webhook-endpoints/{id}` — Eliminar endpoint
- `POST   /webhook-endpoints/{id}/test` — Enviar evento de prueba
- `POST   /webhook-endpoints/{id}/rotate-secret` — Rotar secret
- `GET    /webhook-endpoints/{id}/deliveries` — Ver entregas
- `POST   /webhook-endpoints/{id}/deliveries/{delivery_id}/resend` — Reenviar

### Conversaciones (WhatsApp)
- `GET    /conversations` — Listar conversaciones
- `GET    /conversations/{id}` — Ver conversación con mensajes
- `POST   /conversations/{id}/messages` — Enviar mensaje (body)
- `POST   /conversations/{id}/close` — Cerrar conversación

### Templates de WhatsApp (HSM)
- `GET    /whatsapp-templates` — Listar templates aprobados
- `POST   /whatsapp-templates/{id}/send` — Enviar template (customer_id, parameters?)

### Seguimientos (Cobranza)
- `GET    /follow-ups` — Listar seguimientos (?status=pending|completed|overdue)
- `POST   /follow-ups` — Crear (customer_id, title, description?, due_date, type: call|email|whatsapp|visit|other)
- `PUT    /follow-ups/{id}` — Actualizar
- `POST   /follow-ups/{id}/complete` — Marcar completado

### Productos (Tienda)
- `GET    /products` — Listar productos
- `POST   /products` — Crear (name, price, description?, sku?, stock?)
- `PUT    /products/{id}` — Actualizar
- `DELETE /products/{id}` — Eliminar

### Pedidos (Tienda)
- `GET    /orders` — Listar pedidos
- `GET    /orders/{id}` — Ver pedido
- `PUT    /orders/{id}/status` — Cambiar status (status: pending|processing|shipped|delivered|cancelled)

### Equipo
- `GET    /team` — Listar miembros del equipo

### Fuentes de Clientes
- `GET    /customer-sources` — Listar fuentes de clientes

## Paginación
Todas las listas devuelven paginación:
```json
{
  "data": [...],
  "meta": { "current_page": 1, "last_page": 5, "per_page": 25, "total": 112 },
  "links": { "next": "...?page=2", "prev": null }
}
```
Parámetros: `?page=1&per_page=25` (máximo 100).

## Errores
```json
{
  "error": { "code": "validation_error", "message": "...", "details": {...} }
}
```
Códigos HTTP: 200 OK, 201 Created, 400 Bad Request, 401 Unauthorized, 404 Not Found, 422 Unprocessable, 429 Rate Limited, 500 Server Error.

## MCP Server (recomendado para Claude Code)
Si usas Claude Code, conecta el MCP server para acceso directo:
```bash
claude mcp add recaudo -e RECAUDO_API_KEY=sk_live_tu_key -- npx -y @recaudo/mcp-server
```
Esto te da 139 herramientas nativas sin necesidad de hacer requests HTTP manuales.

## Ejemplo rápido: crear cliente + link de pago
```bash
# 1. Crear cliente
curl -X POST https://recaudo.app/api/v1/customers \
  -H "Authorization: Bearer sk_live_..." \
  -H "Content-Type: application/json" \
  -d '{"name": "Juan Pérez", "email": "juan@email.com", "phone": "+5255123456"}'

# 2. Crear link de pago
curl -X POST https://recaudo.app/api/v1/payment-links \
  -H "Authorization: Bearer sk_live_..." \
  -H "Content-Type: application/json" \
  -d '{"title": "Consultoría", "amount": 1500.00, "currency": "MXN"}'
```

## Notas para el agente
- Siempre validar que la respuesta sea 2xx antes de proceder.
- Los IDs son UUIDs (formato: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx).
- El rate limit es 60 requests/minuto por API key.
- Para desarrollo, usa API keys de prueba (prefijo sk_test_).
- La moneda por defecto es MXN si no se especifica.

Claude Code

Pega las instrucciones en CLAUDE.md en la raíz de tu proyecto.

Cursor / Windsurf

Pega en .cursorrules o .windsurfrules en la raíz.

Codex / Copilot

Pega en AGENTS.md o inclúyelo en el prompt del sistema.

Tip: Si usas Claude Code, la mejor opción es conectar el MCP Server directamente. Así el agente tiene acceso a 139 herramientas nativas sin necesidad de copiar estas instrucciones. Solo ejecuta claude mcp add recaudo -e RECAUDO_API_KEY=sk_live_... -- npx -y @recaudo/mcp-server

Manejo de Errores

La API utiliza codigos de estado HTTP convencionales para indicar el exito o fallo de una peticion.

Codigo Descripcion
200 Peticion exitosa
201 Recurso creado exitosamente
400 Peticion invalida - revisa los parametros
401 No autorizado - API key invalida o faltante
403 Prohibido - no tienes permisos para este recurso
404 Recurso no encontrado
422 Error de validacion
429 Rate limit excedido
500 Error interno del servidor

Formato de Error

Response
{
  "error": {
    "type": "validation_error",
    "code": "invalid_parameter",
    "message": "El campo email es requerido",
    "param": "email",
    "doc_url": "https://docs.recaudo.app/errors/invalid_parameter"
  }
}

Paginacion

Los endpoints que retornan listas de objetos soportan paginacion basada en cursor.

Parametros

Parametro Tipo Descripcion
limit integer Numero de resultados por pagina (default: 10, max: 100)
starting_after string ID del ultimo objeto de la pagina anterior
ending_before string ID del primer objeto de la pagina siguiente (paginacion hacia atras)

Ejemplo de Respuesta

Response
{
  "object": "list",
  "data": [...],
  "has_more": true,
  "total_count": 150
}

Clientes

Los clientes representan a tus usuarios finales. Puedes asociarles metodos de pago, suscripciones y realizar cargos.

POST /v1/customers

Crear Cliente

Crea un nuevo cliente en tu cuenta.

Parametros

Parametro Tipo Requerido Descripcion
email string Email del cliente
name string Nombre completo
phone string No Teléfono
external_id string No ID del cliente en tu sistema
tax_id string No Identificación fiscal (RFC)
address string No Dirección (calle y número). Requerido para AMEX
city string No Ciudad. Requerido para AMEX
state string No Estado o provincia. Requerido para AMEX
postal_code string No Código postal. Requerido para AMEX
country string No Código de país ISO 3166-1 alpha-2 (ej: MX, US, CO). Requerido para AMEX
metadata object No Datos adicionales (max 50 keys)
curl -X POST https://recaudo.app/api/v1/customers \
  -H "Authorization: Bearer sk_live_xxx" \
  -H "Content-Type: application/json" \
  -d '{
    "email": "cliente@ejemplo.com",
    "name": "Juan Pérez",
    "phone": "+52 55 1234 5678",
    "address": "Av. Reforma 123, Col. Centro",
    "city": "Ciudad de México",
    "state": "CDMX",
    "postal_code": "06600",
    "country": "MX",
    "tax_id": "XAXX010101000",
    "metadata": {
      "user_id": "usr_123"
    }
  }'
$response = $client->post('/api/v1/customers', [
    'json' => [
        'email' => 'cliente@ejemplo.com',
        'name' => 'Juan Pérez',
        'phone' => '+52 55 1234 5678',
        'address' => 'Av. Reforma 123, Col. Centro',
        'city' => 'Ciudad de México',
        'state' => 'CDMX',
        'postal_code' => '06600',
        'country' => 'MX',
        'tax_id' => 'XAXX010101000',
        'metadata' => ['user_id' => 'usr_123']
    ]
]);
const customer = await fetch('/api/v1/customers', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer sk_live_xxx',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    email: 'cliente@ejemplo.com',
    name: 'Juan Pérez',
    phone: '+52 55 1234 5678',
    address: 'Av. Reforma 123, Col. Centro',
    city: 'Ciudad de México',
    state: 'CDMX',
    postal_code: '06600',
    country: 'MX',
    tax_id: 'XAXX010101000',
    metadata: { user_id: 'usr_123' }
  })
});
response = requests.post(
    'https://recaudo.app/api/v1/customers',
    headers={'Authorization': 'Bearer sk_live_xxx'},
    json={
        'email': 'cliente@ejemplo.com',
        'name': 'Juan Pérez',
        'phone': '+52 55 1234 5678',
        'address': 'Av. Reforma 123, Col. Centro',
        'city': 'Ciudad de México',
        'state': 'CDMX',
        'postal_code': '06600',
        'country': 'MX',
        'tax_id': 'XAXX010101000',
        'metadata': {'user_id': 'usr_123'}
    }
)
Response 201
{
  "object": "customer",
  "data": {
    "id": "cus_a1b2c3d4e5f6",
    "email": "cliente@ejemplo.com",
    "name": "Juan Pérez",
    "phone": "+52 55 1234 5678",
    "address": "Av. Reforma 123, Col. Centro",
    "city": "Ciudad de México",
    "state": "CDMX",
    "postal_code": "06600",
    "country": "MX",
    "tax_id": "XAXX010101000",
    "metadata": { "user_id": "usr_123" },
    "created_at": "2024-01-15T10:30:00Z"
  }
}
GET /v1/customers

Listar Clientes

Obtiene una lista paginada de todos los clientes.

Request
curl https://recaudo.app/api/v1/customers?limit=10 \
  -H "Authorization: Bearer sk_live_xxx"
Response 200
{
  "object": "list",
  "data": [
    {
      "id": "cus_a1b2c3d4e5f6",
      "object": "customer",
      "email": "cliente@ejemplo.com",
      "name": "Juan Perez",
      ...
    }
  ],
  "has_more": true,
  "total_count": 150
}
GET /v1/customers/:id

Obtener Cliente

Obtiene los detalles de un cliente existente.

PATCH /v1/customers/:id

Actualizar Cliente

Actualiza los datos de un cliente. Solo se modifican los campos enviados.

DELETE /v1/customers/:id

Eliminar Cliente

Elimina un cliente y sus datos asociados. Esta accion no se puede deshacer.

Cargos Directos

Realiza cargos directos a metodos de pago guardados. Ideal para cargos recurrentes o one-click payments.

POST /v1/charges

Crear Cargo

Realiza un cargo a un metodo de pago guardado.

Parametros

Parametro Tipo Requerido Descripcion
amount number Si Monto en decimales (ej: 100.00 = $100.00)
currency string Si Codigo ISO de moneda
payment_method string Condicional* ID del método de pago guardado
token string Condicional* Token de tarjeta generado con recaudo.js (tok_xxx para Conekta, pm_xxx para Stripe)
card object No Info de tarjeta de recaudo.js: { brand, last4, exp_month, exp_year }. Recomendado para mejor tracking
customer string Condicional* ID del cliente (requerido si usa payment_method)
description string No Descripcion del cargo
Request
curl -X POST https://recaudo.app/api/v1/charges \
  -H "Authorization: Bearer sk_live_xxx" \
  -H "Content-Type: application/json" \
  -d '{
    "amount": 250.00,
    "currency": "MXN",
    "token": "tok_abc123...",
    "card": {
      "brand": "visa",
      "last4": "4242",
      "exp_month": 12,
      "exp_year": 2027
    },
    "description": "Cargo por servicio premium"
  }'
Response 201
{
  "id": "ch_abc123def456",
  "object": "charge",
  "amount": 250.00,
  "currency": "MXN",
  "status": "succeeded",
  "customer_id": "cus_a1b2c3d4e5f6",
  "payment_method_id": "pm_card_xyz123",
  "description": "Cargo por servicio premium",
  "payment_intent_id": "pi_789xyz",
  "receipt_url": "https://pay.recaudo.app/receipts/ch_abc123",
  "created_at": "2024-01-15T10:30:00Z"
}
POST /v1/charges/:id/refund

Reembolsar Cargo

Realiza un reembolso total o parcial de un cargo.

Request (reembolso parcial)
curl -X POST https://recaudo.app/api/v1/charges/ch_abc123/refund \
  -H "Authorization: Bearer sk_live_xxx" \
  -H "Content-Type: application/json" \
  -d '{
    "amount": 100.00,
    "reason": "customer_request"
  }'
Response 200
{
  "id": "re_xyz789abc",
  "object": "refund",
  "amount": 100.00,
  "currency": "MXN",
  "charge_id": "ch_abc123def456",
  "status": "succeeded",
  "reason": "customer_request",
  "created_at": "2024-01-15T11:00:00Z"
}

Tokenización

Tokeniza tarjetas de forma segura directamente desde tu frontend usando recaudo.js v2. La librería carga automáticamente el SDK del procesador de pagos (Conekta, Stripe) configurado en tu cuenta y tokeniza la tarjeta de manera transparente.

White-label checkout: Este sistema te permite crear tu propia página de checkout sin necesidad de redirigir a páginas externas. Los datos de tarjeta nunca pasan por tu servidor.

Integración en 4 pasos

1

Incluir la librería JavaScript

HTML
<script src="https://recaudo.app/js/recaudo.min.js"></script>
2

Inicializar la librería

Inicializa recaudo.js con tu Publishable Key. El método init() carga el SDK del procesador configurado.

JavaScript
// Crear instancia con tu Publishable Key
const recaudo = new Recaudo('pk_live_tu_publishable_key');

// Inicializar (carga el SDK del procesador automáticamente)
await recaudo.init();

// Verificar que está listo
console.log('Gateway:', recaudo.getGateway()); // 'conekta' o 'stripe'
3

Tokenizar la tarjeta

Los datos de la tarjeta se tokenizan directamente con el procesador de pagos. Nunca pasan por tu servidor.

JavaScript
async function handlePayment() {
  try {
    const token = await recaudo.createToken({
      number: '4242424242424242',
      exp_month: 12,
      exp_year: 2027,
      cvv: '123',
      name: 'Juan Pérez',
      email: 'juan@example.com',
      // Campos opcionales (requeridos para AMEX)
      address: 'Av. Reforma 123',
      city: 'CDMX',
      state: 'CDMX',
      postal_code: '06600',
      country: 'MX'
    });

    // token contiene:
    // - id: Token del procesador (tok_xxx para Conekta, pm_xxx para Stripe)
    // - gateway: 'conekta' o 'stripe'
    // - card: { brand, last4, exp_month, exp_year }

    // Enviar al backend para procesar
    await fetch('/tu-backend/procesar-pago', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({
        token: token.id,
        card: token.card,  // Incluir info de tarjeta para mejor tracking
        amount: 100.00
      })
    });

  } catch (error) {
    // error.type: 'validation_error', 'gateway_error', 'sdk_error'
    console.error('Error:', error.message);
  }
}
4

Procesar el cobro desde tu backend

Usa el token para crear un cargo o una suscripción. Incluye el objeto card para mejor tracking.

cURL - Cargo directo
curl -X POST https://recaudo.app/api/v1/charges \
  -H "Authorization: Bearer sk_live_tu_secret_key" \
  -H "Content-Type: application/json" \
  -d '{
    "amount": 100.00,
    "currency": "MXN",
    "token": "tok_abc123...",
    "card": {
      "brand": "visa",
      "last4": "4242",
      "exp_month": 12,
      "exp_year": 2027
    },
    "description": "Compra en tienda",
    "receipt_email": "cliente@example.com"
  }'
cURL - Crear suscripción
curl -X POST https://recaudo.app/api/v1/subscriptions \
  -H "Authorization: Bearer sk_live_tu_secret_key" \
  -H "Content-Type: application/json" \
  -d '{
    "plan": "plan_uuid_here",
    "customer": "cus_uuid_here",
    "token": "tok_abc123...",
    "card": {
      "brand": "visa",
      "last4": "4242",
      "exp_month": 12,
      "exp_year": 2027
    }
  }'

Objeto Token (respuesta de createToken)

Respuesta de createToken()
{
  "id": "tok_2sR5Vx1J5K...",  // Token del procesador (tok_xxx Conekta, pm_xxx Stripe)
  "gateway": "conekta",       // Procesador utilizado
  "card": {
    "brand": "visa",
    "last4": "4242",
    "exp_month": 12,
    "exp_year": 2027
  },
  "created_at": "2024-01-15T10:30:00.000Z"
}

Endpoints de la API

Método Endpoint Descripción
GET /v1/tokens/config Obtener configuración del procesador (usado por recaudo.js para cargar el SDK correcto)
GET /v1/tokens/public-key Obtener clave pública para encriptación (legacy v1)
POST /v1/tokens Crear token desde datos encriptados (legacy v1)
GET /v1/tokens/:token Obtener información de un token
DELETE /v1/tokens/:token Eliminar un token

Métodos de recaudo.js

Método Descripción
new Recaudo(publishableKey) Constructor. Crea una instancia con tu Publishable Key.
init() Carga el SDK del procesador configurado. Debe llamarse antes de createToken().
createToken(cardData) Tokeniza los datos de la tarjeta con el procesador.
getGateway() Retorna el nombre del procesador ('conekta', 'stripe').
isInitialized() Retorna true si init() ya fue llamado.
detectCardBrand(number) Detecta la marca de la tarjeta (visa, mastercard, amex, etc).
Seguridad: Los tokens son generados directamente por el procesador de pagos (Conekta/Stripe). Los datos de tarjeta nunca pasan por los servidores de Recaudo ni por tu servidor, facilitando el cumplimiento de PCI DSS.

Manejo de Errores

Los errores de recaudo.js incluyen un tipo para facilitar su manejo:

Ejemplo de manejo de errores
try {
  await recaudo.init();
  const token = await recaudo.createToken(cardData);
} catch (error) {
  switch (error.type) {
    case 'validation_error':
      // Datos de tarjeta inválidos
      showError(error.message);
      break;
    case 'gateway_error':
      // Error del procesador (tarjeta rechazada, etc)
      showError(error.message);
      break;
    case 'sdk_error':
      // Error cargando el SDK del procesador
      showError('Error de conexión. Intenta de nuevo.');
      break;
    case 'configuration_error':
      // Procesador no configurado
      showError('Error de configuración.');
      break;
    default:
      showError('Error inesperado.');
  }
}

Suscripciones

Las suscripciones te permiten cobrar de forma recurrente a tus clientes. Soportan periodos de prueba, pausas y cambios de plan.

POST /v1/subscriptions

Crear Suscripción

Crea una nueva suscripción para un cliente. Puedes usar un método de pago almacenado o un token de recaudo.js.

Tokenización: Puedes usar el parámetro token con un token de recaudo.js (tok_xxx) en lugar de payment_method. El token será convertido automáticamente en un método de pago almacenado.

Parámetros

Parámetro Tipo Requerido Descripción
customer string (uuid) ID del cliente
plan string (uuid) ID del plan de suscripción
payment_method string (uuid) No* ID de método de pago almacenado. Requerido si no hay trial y no se usa token.
token string No* Token de recaudo.js (tok_xxx para Conekta, pm_xxx para Stripe). Alternativa a payment_method.
card object No Info de tarjeta de recaudo.js: { brand, last4, exp_month, exp_year }. Recomendado para mejor tracking
trial_days integer No Días de prueba (0-365)
amount numeric No Monto personalizado (override del plan)
metadata object No Datos adicionales
curl -X POST https://recaudo.app/api/v1/subscriptions \
  -H "Authorization: Bearer sk_live_xxx" \
  -H "Content-Type: application/json" \
  -d '{
    "customer": "550e8400-e29b-41d4-a716-446655440000",
    "plan": "660e8400-e29b-41d4-a716-446655440001",
    "token": "tok_abc123def456",
    "card": {
      "brand": "visa",
      "last4": "4242",
      "exp_month": 12,
      "exp_year": 2027
    },
    "metadata": {
      "signup_source": "landing_page"
    }
  }'
curl -X POST https://recaudo.app/api/v1/subscriptions \
  -H "Authorization: Bearer sk_live_xxx" \
  -H "Content-Type: application/json" \
  -d '{
    "customer": "550e8400-e29b-41d4-a716-446655440000",
    "plan": "660e8400-e29b-41d4-a716-446655440001",
    "payment_method": "770e8400-e29b-41d4-a716-446655440002",
    "metadata": {
      "signup_source": "landing_page"
    }
  }'
Response 201
{
  "id": "sub_1a2b3c4d5e6f",
  "object": "subscription",
  "status": "active",
  "customer_id": "cus_a1b2c3d4e5f6",
  "plan": {
    "id": "plan_premium_monthly",
    "name": "Premium Mensual",
    "amount": 299.00,
    "currency": "MXN",
    "interval": "month"
  },
  "current_period_start": "2024-01-15T00:00:00Z",
  "current_period_end": "2024-02-15T00:00:00Z",
  "trial_end": null,
  "cancel_at_period_end": false,
  "created_at": "2024-01-15T10:30:00Z"
}

Acciones de Suscripcion

POST /v1/subscriptions/:id/cancel Cancelar suscripcion
curl -X POST https://recaudo.app/api/v1/subscriptions/sub_1a2b3c/cancel \
  -H "Authorization: Bearer sk_live_xxx" \
  -d '{"cancel_at_period_end": true, "reason": "too_expensive"}'
POST /v1/subscriptions/:id/pause Pausar suscripcion
curl -X POST https://recaudo.app/api/v1/subscriptions/sub_1a2b3c/pause \
  -H "Authorization: Bearer sk_live_xxx"
POST /v1/subscriptions/:id/resume Reanudar suscripcion
curl -X POST https://recaudo.app/api/v1/subscriptions/sub_1a2b3c/resume \
  -H "Authorization: Bearer sk_live_xxx"

Facturas

Las facturas permiten gestionar cobros con soporte completo para parcialidades (pagos en cuotas), políticas de moratorios y seguimiento detallado de pagos. Ideal para colegiaturas, créditos y servicios recurrentes.

Endpoints Disponibles

GET /v1/invoices Listar facturas
POST /v1/invoices Crear factura (con o sin parcialidades)
GET /v1/invoices/:id Obtener factura
PATCH /v1/invoices/:id Actualizar factura
DELETE /v1/invoices/:id Eliminar factura
POST /v1/invoices/:id/pay Marcar como pagada
POST /v1/invoices/:id/void Anular factura
GET /v1/invoices/:id/installments Listar parcialidades
PATCH /v1/invoices/:id/installments/:installment_id Actualizar parcialidad

Crear Factura

Crea una factura con items y opcionalmente configura parcialidades automáticas o manuales.

curl -X POST https://recaudo.app/api/v1/invoices \
  -H "Authorization: Bearer sk_live_tu_secret_key" \
  -H "Content-Type: application/json" \
  -d '{
    "customer_id": "cus_abc123",
    "document_date": "2024-01-15",
    "items": [
      {
        "description": "Colegiatura Enero 2024",
        "quantity": 1,
        "unit_price": 5000.00
      }
    ],
    "has_installments": true,
    "installment_count": 3,
    "installment_frequency": "monthly",
    "first_installment_due_date": "2024-01-20"
  }'
$response = $client->post('https://recaudo.app/api/v1/invoices', [
    'headers' => [
        'Authorization' => 'Bearer sk_live_tu_secret_key',
        'Content-Type' => 'application/json',
    ],
    'json' => [
        'customer_id' => 'cus_abc123',
        'document_date' => '2024-01-15',
        'items' => [
            [
                'description' => 'Colegiatura Enero 2024',
                'quantity' => 1,
                'unit_price' => 5000.00,
            ]
        ],
        'has_installments' => true,
        'installment_count' => 3,
        'installment_frequency' => 'monthly',
        'first_installment_due_date' => '2024-01-20',
    ]
]);
const response = await fetch('https://recaudo.app/api/v1/invoices', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer sk_live_tu_secret_key',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    customer_id: 'cus_abc123',
    document_date: '2024-01-15',
    items: [
      {
        description: 'Colegiatura Enero 2024',
        quantity: 1,
        unit_price: 5000.00
      }
    ],
    has_installments: true,
    installment_count: 3,
    installment_frequency: 'monthly',
    first_installment_due_date: '2024-01-20'
  })
});
response = requests.post(
    'https://recaudo.app/api/v1/invoices',
    headers={
        'Authorization': 'Bearer sk_live_tu_secret_key',
        'Content-Type': 'application/json',
    },
    json={
        'customer_id': 'cus_abc123',
        'document_date': '2024-01-15',
        'items': [
            {
                'description': 'Colegiatura Enero 2024',
                'quantity': 1,
                'unit_price': 5000.00
            }
        ],
        'has_installments': True,
        'installment_count': 3,
        'installment_frequency': 'monthly',
        'first_installment_due_date': '2024-01-20'
    }
)

Parámetros de Parcialidades

Parámetro Tipo Descripción
has_installments boolean Habilitar parcialidades
installment_count integer Número de parcialidades (2-48)
installment_frequency string weekly, biweekly o monthly
first_installment_due_date date Fecha de vencimiento de la primera parcialidad
late_fee_policy_id uuid ID de política de moratorios

Parcialidades Manuales

Para mayor control, puedes definir cada parcialidad manualmente con sus propias fechas, montos y estado de pago. Útil para importar facturas existentes con pagos parciales.

Manual Installments Example
{
  "customer_id": "cus_abc123",
  "items": [
    { "description": "Servicio anual", "quantity": 1, "unit_price": 12000.00 }
  ],
  "installments": [
    {
      "due_date": "2024-01-15",
      "amount": 4000.00,
      "external_id": "FACT-001-P1",
      "is_paid": true,
      "amount_paid": 4000.00,
      "paid_at": "2024-01-10"
    },
    {
      "due_date": "2024-02-15",
      "amount": 4000.00,
      "external_id": "FACT-001-P2",
      "is_paid": false
    },
    {
      "due_date": "2024-03-15",
      "amount": 4000.00,
      "external_id": "FACT-001-P3",
      "is_paid": false
    }
  ]
}

Objeto Invoice

Invoice Object with Installments
{
  "id": "inv_abc123xyz",
  "object": "invoice",
  "invoice_number": "INV-2024-0001",
  "external_id": "FACT-001",
  "status": "partial",
  "customer_id": "cus_a1b2c3d4e5f6",
  "currency": "MXN",
  "subtotal": 5000.00,
  "tax_amount": 0,
  "total": 5000.00,
  "amount_paid": 1666.67,
  "amount_due": 3333.33,
  "document_date": "2024-01-15",
  "due_date": "2024-03-20",
  "has_installments": true,
  "installment_count": 3,
  "installment_frequency": "monthly",
  "items": [
    {
      "id": "ii_xyz789",
      "description": "Colegiatura Enero 2024",
      "quantity": 1,
      "unit_price": 5000.00,
      "total": 5000.00
    }
  ],
  "installments": [
    {
      "id": "inst_001",
      "installment_number": 1,
      "status": "paid",
      "principal_amount": 1666.67,
      "late_fee_amount": 0,
      "total_amount": 1666.67,
      "amount_paid": 1666.67,
      "amount_due": 0,
      "due_date": "2024-01-20",
      "paid_at": "2024-01-18T14:30:00Z",
      "days_overdue": 0,
      "external_id": null
    },
    {
      "id": "inst_002",
      "installment_number": 2,
      "status": "pending",
      "principal_amount": 1666.67,
      "late_fee_amount": 0,
      "total_amount": 1666.67,
      "amount_paid": 0,
      "amount_due": 1666.67,
      "due_date": "2024-02-20",
      "paid_at": null,
      "days_overdue": 0,
      "external_id": null
    },
    {
      "id": "inst_003",
      "installment_number": 3,
      "status": "pending",
      "principal_amount": 1666.66,
      "late_fee_amount": 0,
      "total_amount": 1666.66,
      "amount_paid": 0,
      "amount_due": 1666.66,
      "due_date": "2024-03-20",
      "paid_at": null,
      "days_overdue": 0,
      "external_id": null
    }
  ],
  "created_at": "2024-01-15T00:00:00Z"
}

Estados de Parcialidades

Estado Descripción
pending Pendiente de pago, no vencida
partial Pago parcial recibido
paid Completamente pagada
overdue Vencida sin pagar (puede generar moratorios)
cancelled Cancelada (factura anulada)

Moratorios

Las parcialidades vencidas pueden generar moratorios automáticamente según la política configurada. El campo late_fee_amount muestra el moratorio acumulado y se suma al total_amount de la parcialidad.

Importante: Los moratorios se calculan sobre el saldo pendiente del principal, no sobre moratorios previos (evita interés compuesto no deseado).

Webhooks

Los webhooks te permiten recibir notificaciones en tiempo real sobre eventos en tu cuenta. Configura un endpoint HTTPS y recibe actualizaciones automaticas.

Tipos de Eventos

Pagos

  • payment.created
  • payment.succeeded
  • payment.failed
  • payment.refunded

Links de Pago

  • payment_link.created
  • payment_link.paid
  • payment_link.expired

Suscripciones

  • subscription.created
  • subscription.updated
  • subscription.canceled
  • subscription.paused
  • subscription.resumed
  • subscription.trial_ending

Facturas

  • invoice.created
  • invoice.paid
  • invoice.payment_failed
  • invoice.upcoming

Formato del Payload

Webhook Payload
{
  "id": "evt_1a2b3c4d5e6f",
  "object": "event",
  "type": "payment.succeeded",
  "api_version": "2024-01-01",
  "created": 1705312200,
  "data": {
    "object": {
      "id": "pi_abc123xyz",
      "object": "payment_intent",
      "amount": 500.00,
      "currency": "MXN",
      "status": "succeeded",
      "customer_id": "cus_a1b2c3d4e5f6",
      ...
    }
  }
}

Verificacion de Firma (HMAC)

Cada webhook incluye un header X-Recaudo-Signature que debes verificar para asegurar que el mensaje viene de Recaudo.

<?php
// Obtener el payload y la firma
$payload = file_get_contents('php://input');
$signature = $_SERVER['HTTP_X_RECAUDO_SIGNATURE'];
$secret = 'whsec_tu_webhook_secret';

// Extraer timestamp y firma del header
// Formato: t=timestamp,v1=signature
$parts = explode(',', $signature);
$timestamp = substr($parts[0], 2);
$receivedSignature = substr($parts[1], 3);

// Calcular la firma esperada
$signedPayload = $timestamp . '.' . $payload;
$expectedSignature = hash_hmac('sha256', $signedPayload, $secret);

// Verificar
if (hash_equals($expectedSignature, $receivedSignature)) {
    // Firma valida - procesar el evento
    $event = json_decode($payload, true);

    switch ($event['type']) {
        case 'payment.succeeded':
            // Manejar pago exitoso
            break;
        case 'subscription.canceled':
            // Manejar cancelacion
            break;
    }

    http_response_code(200);
} else {
    // Firma invalida
    http_response_code(400);
}
const crypto = require('crypto');

app.post('/webhooks/recaudo', express.raw({type: 'application/json'}), (req, res) => {
  const payload = req.body;
  const signature = req.headers['x-recaudo-signature'];
  const secret = 'whsec_tu_webhook_secret';

  // Extraer timestamp y firma
  const parts = signature.split(',');
  const timestamp = parts[0].split('=')[1];
  const receivedSignature = parts[1].split('=')[1];

  // Calcular firma esperada
  const signedPayload = `${timestamp}.${payload}`;
  const expectedSignature = crypto
    .createHmac('sha256', secret)
    .update(signedPayload)
    .digest('hex');

  // Verificar
  if (crypto.timingSafeEqual(
    Buffer.from(expectedSignature),
    Buffer.from(receivedSignature)
  )) {
    const event = JSON.parse(payload);

    switch (event.type) {
      case 'payment.succeeded':
        // Manejar pago exitoso
        break;
      case 'subscription.canceled':
        // Manejar cancelacion
        break;
    }

    res.status(200).send('OK');
  } else {
    res.status(400).send('Invalid signature');
  }
});
import hmac
import hashlib
from flask import Flask, request

app = Flask(__name__)

@app.route('/webhooks/recaudo', methods=['POST'])
def webhook():
    payload = request.data
    signature = request.headers.get('X-Recaudo-Signature')
    secret = 'whsec_tu_webhook_secret'

    # Extraer timestamp y firma
    parts = signature.split(',')
    timestamp = parts[0].split('=')[1]
    received_signature = parts[1].split('=')[1]

    # Calcular firma esperada
    signed_payload = f"{timestamp}.{payload.decode()}"
    expected_signature = hmac.new(
        secret.encode(),
        signed_payload.encode(),
        hashlib.sha256
    ).hexdigest()

    # Verificar
    if hmac.compare_digest(expected_signature, received_signature):
        event = request.json

        if event['type'] == 'payment.succeeded':
            # Manejar pago exitoso
            pass
        elif event['type'] == 'subscription.canceled':
            # Manejar cancelacion
            pass

        return 'OK', 200
    else:
        return 'Invalid signature', 400

Mejores Practicas

  • Siempre verifica la firma HMAC antes de procesar el evento
  • Responde con 200 rapidamente y procesa de forma asincrona
  • Implementa idempotencia usando el ID del evento
  • Usa HTTPS con un certificado valido
  • Los webhooks se reintentan automaticamente si fallas (hasta 3 veces)

API de Webhook Endpoints

Administra tus webhook endpoints programáticamente.

POST /v1/webhook-endpoints

Crear un nuevo webhook endpoint.

Request Body
{
  "url": "https://tu-servidor.com/webhooks/recaudo",
  "events": ["payment.succeeded", "invoice.paid", "customer.created"],
  "description": "Webhook principal de producción",
  "is_active": true
}
GET /v1/webhook-endpoints

Listar todos los webhook endpoints configurados.

GET /v1/webhook-endpoints/{'{id}'}

Ver detalle del endpoint incluyendo el secret para verificar firmas.

Response
{
  "id": "we_abc123",
  "url": "https://tu-servidor.com/webhooks/recaudo",
  "events": ["payment.succeeded", "invoice.paid"],
  "secret": "whsec_tu_webhook_secret",
  "is_active": true,
  "description": "Webhook principal",
  "created_at": "2026-04-01T00:00:00Z"
}
PUT /v1/webhook-endpoints/{'{id}'}

Actualizar URL, eventos o estado del endpoint.

Request Body
{
  "url": "https://nueva-url.com/webhooks",
  "events": ["payment.succeeded", "payment.failed"],
  "is_active": false
}
DELETE /v1/webhook-endpoints/{'{id}'}

Eliminar un webhook endpoint.

POST /v1/webhook-endpoints/{'{id}'}/test

Enviar un evento de prueba al endpoint para verificar la conectividad.

POST /v1/webhook-endpoints/{'{id}'}/rotate-secret

Generar un nuevo secret para el endpoint. El secret anterior dejará de ser válido inmediatamente.

GET /v1/webhook-endpoints/{'{id}'}/deliveries

Ver el historial de entregas del endpoint con status y response codes.

POST /v1/webhook-endpoints/{'{id}'}/deliveries/{'{delivery_id}'}/resend

Reenviar una entrega fallida.

Productos

Gestiona tu catálogo de productos y categorías. Los productos pueden tener control de inventario, precios de comparación, impuestos y metadatos personalizados.

Listar categorías

GET /v1/product-categories

Parámetros opcionales: is_active, parent_id (UUID o "root"), limit, page

Crear categoría

POST /v1/product-categories
Body
{
  "name": "Electrónicos",
  "description": "Productos electrónicos y gadgets",
  "parent_id": null,
  "sort_order": 1,
  "is_active": true
}
Campo Tipo Requerido Descripción
namestringNombre de la categoría
parent_iduuidNoCategoría padre (para subcategorías)
descriptionstringNoDescripción
sort_orderintegerNoOrden de visualización
is_activebooleanNoSi está activa (default: true)

Obtener / Actualizar / Eliminar categoría

GET /v1/product-categories/{'{id}'}
PATCH /v1/product-categories/{'{id}'}
DELETE /v1/product-categories/{'{id}'}

Al eliminar una categoría, sus subcategorías se mueven al padre y los productos se desvinculan.


Listar productos

GET /v1/products

Parámetros opcionales: status (active, draft, archived), category (UUID), search, featured, in_stock, limit, page

Crear producto

POST /v1/products
Body
{
  "name": "Laptop Pro 15",
  "price": 25999.00,
  "currency": "MXN",
  "sku": "LAP-PRO-15",
  "description": "Laptop profesional de 15 pulgadas",
  "product_category_id": "uuid-de-la-categoria",
  "track_stock": true,
  "stock_quantity": 50,
  "tax_rate": 16,
  "is_featured": true,
  "metadata": {
    "brand": "TechCorp",
    "warranty_months": 24
  }
}
Campo Tipo Requerido Descripción
namestringNombre del producto
pricenumberPrecio en decimales (100.00 = $100)
currencystringNoMoneda ISO 4217 (default según tenant)
statusstringNoactive, draft, archived (default: active)
product_category_iduuidNoUUID de la categoría
skustringNoCódigo SKU
descriptionstringNoDescripción larga
compare_at_pricenumberNoPrecio de comparación (antes)
cost_pricenumberNoCosto del producto
track_stockbooleanNoActivar control de inventario
stock_quantityintegerNoCantidad en stock
tax_ratenumberNoTasa de impuesto (%)
is_featuredbooleanNoProducto destacado
image_urlurlNoURL de la imagen
metadataobjectNoMetadatos personalizados

Obtener / Actualizar / Eliminar producto

GET /v1/products/{'{id}'}
PATCH /v1/products/{'{id}'}
DELETE /v1/products/{'{id}'}

No se puede eliminar un producto con pedidos pendientes.

Pedidos

Crea y gestiona pedidos para tus clientes. Al crear un pedido se genera automáticamente una factura y un link de pago. Los precios se toman directamente del catálogo de productos.

Listar pedidos

GET /v1/orders

Parámetros opcionales: status, payment_status, customer (UUID), search, limit, page

Status: pending, confirmed, processing, shipped, delivered, completed, canceled, refunded

Payment status: pending, paid, partially_paid, refunded

Crear pedido

POST /v1/orders
Body
{
  "customer_id": "uuid-del-cliente",
  "items": [
    { "product_id": "uuid-producto-1", "quantity": 2 },
    { "product_id": "uuid-producto-2", "quantity": 1 }
  ],
  "notes": "Entregar antes de las 5pm",
  "shipping_name": "Juan Pérez",
  "shipping_phone": "+5215512345678",
  "shipping_address": "Av. Reforma 123, CDMX"
}
Campo Tipo Requerido Descripción
customer_iduuidUUID del cliente
itemsarrayLista de productos con product_id y quantity
notesstringNoNotas visibles para el cliente
internal_notesstringNoNotas internas
currencystringNoMoneda ISO 4217
shipping_namestringNoNombre del destinatario
shipping_phonestringNoTeléfono del destinatario
shipping_addressstringNoDirección de envío
metadataobjectNoMetadatos personalizados

Obtener pedido

GET /v1/orders/{'{id}'}

Incluye cliente, items con productos y factura asociada.

Ciclo de vida del pedido

POST /v1/orders/{'{id}'}/cancel — Cancelar pedido (restaura stock)
POST /v1/orders/{'{id}'}/ship — Marcar como enviado
POST /v1/orders/{'{id}'}/deliver — Marcar como entregado
POST /v1/orders/{'{id}'}/complete — Marcar como completado

Flujo típico: pending → confirmed → shipped → delivered → completed

Items del pedido

GET /v1/orders/{'{id}'}/items

Retorna los items del pedido con detalle de cada producto.

Conversaciones

Envía y recibe mensajes a través de WhatsApp, Facebook Messenger e Instagram. La API detecta automáticamente el canal de cada conversación y enruta los mensajes al servicio correcto.

Listar conversaciones

GET /v1/conversations

Parámetros opcionales: channel (whatsapp, messenger, instagram), status (open, waiting, resolved, closed), customer (UUID), assigned_to (UUID), limit, page

Obtener conversación

GET /v1/conversations/{'{id}'}

Incluye cliente y agente asignado.

Listar mensajes

GET /v1/conversations/{'{id}'}/messages

Parámetros opcionales: type (text, image, video, audio, document, template), limit, page

Enviar mensaje

POST /v1/conversations/{'{id}'}/messages
Body — Mensaje de texto
{
  "body": "Hola, tu pedido ha sido enviado. Número de guía: ABC123"
}
Body — Mensaje con multimedia
{
  "body": "Aquí está tu factura",
  "media_url": "https://ejemplo.com/factura.pdf",
  "media_type": "document"
}
Campo Tipo Requerido Descripción
bodystringNo*Texto del mensaje (máx 4096 chars)
media_urlurlNo*URL del archivo multimedia
media_typestringNoimage, video, audio, document

* Se requiere al menos body o media_url.

Enviar template de WhatsApp

POST /v1/conversations/{'{id}'}/send-template
Body
{
  "template_id": "uuid-del-template",
  "variables": {
    "1": "Juan Pérez",
    "2": "$1,500.00",
    "3": "15 de marzo"
  }
}

Solo disponible para conversaciones de WhatsApp. Los templates deben estar aprobados por Meta.

Resolver / Cerrar conversación

POST /v1/conversations/{'{id}'}/resolve — Marcar como resuelta
POST /v1/conversations/{'{id}'}/close — Cerrar definitivamente

Flujos de Conversación

La API de Flujos de Conversación te permite desplegar flujos automatizados de WhatsApp a tus clientes, similar a como funcionan las plataformas de engagement como Treble. Puedes iniciar campañas masivas, monitorear el estado de las ejecuciones y actualizar variables en tiempo real.

GET /api/v1/flows

Lista todos los flujos de conversación disponibles para tu tenant.

Respuesta

{
  "object": "list",
  "data": [
    {
      "id": "01234567-89ab-cdef-0123-456789abcdef",
      "name": "Flujo de Cobranza",
      "description": "Recordatorio de pago con opciones",
      "type": "collection",
      "purpose": "Recordatorio",
      "channel": "whatsapp",
      "status": "published",
      "version": 1,
      "total_runs": 150,
      "total_responses": 89,
      "response_rate": 59.3,
      "published_at": "2024-01-15T10:30:00Z",
      "created_at": "2024-01-10T08:00:00Z",
      "updated_at": "2024-01-15T10:30:00Z"
    }
  ],
  "url": "/v1/flows"
}
POST /api/v1/flows/{flow_id}/deploy

Despliega un flujo a uno o más destinatarios. Cada destinatario recibirá el flujo de forma independiente. Puedes incluir variables personalizadas que se usarán para reemplazar placeholders en los mensajes.

Cuerpo de la Petición

{
  "recipients": [
    {
      "phone": "+5215512345678",
      "variables": {
        "nombre": "Juan Pérez",
        "monto": "$1,500.00",
        "fecha_limite": "15 de febrero"
      }
    },
    {
      "phone": "+5215587654321",
      "variables": {
        "nombre": "María García",
        "monto": "$2,300.00",
        "fecha_limite": "20 de febrero"
      }
    }
  ],
  "phone_number_id": "uuid-de-tu-numero-whatsapp", // Opcional: número desde el cual sale el flow. Si se omite, usa el default del tenant.
  "scheduled_at": null                              // Opcional: programar para después
}

phone_number_id identifica el número desde el cual sale el flow. Acepta dos formatos: el UUID interno del PhoneNumber, o el meta_phone_number_id (el ID numérico que Meta asigna al número, ej. 748899301642932). Lo puedes obtener desde /admin/settings/integrations/whatsapp/numbers. Si tu tenant solo tiene un número de WhatsApp, no es necesario enviarlo.

Respuesta

{
  "success": true,
  "message": "Flow deployed to 2 recipients",
  "data": {
    "flow_id": "01234567-89ab-cdef-0123-456789abcdef",
    "batch_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "total_recipients": 2,
    "runs_created": 2,
    "scheduled_at": null,
    "run_ids": [
      "f1a2b3c4-d5e6-7890-abcd-111111111111",
      "f1a2b3c4-d5e6-7890-abcd-222222222222"
    ]
  }
}
GET /api/v1/flows/{flow_id}/runs

Lista las ejecuciones de un flujo con filtros opcionales.

Parámetros de Query

Parámetro Tipo Descripción
status string Filtrar por estado: pending, running, waiting, completed, failed, cancelled
batch_id string Filtrar por ID de lote (retornado en el deploy)
phone string Filtrar por número de teléfono del destinatario
limit integer Resultados por página (default 20)

Respuesta

{
  "object": "list",
  "data": [
    {
      "id": "f1a2b3c4-d5e6-7890-abcd-111111111111",
      "flow_id": "01234567-89ab-cdef-0123-456789abcdef",
      "flow_name": "Flujo de Cobranza",
      "phone_number": "+5215512345678",
      "country_code": "MX",
      "customer_id": "cust-uuid-123",
      "customer_name": "Juan Pérez",
      "conversation_id": "conv-uuid-789",
      "status": "completed",
      "source": "api",
      "batch_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
      "context": {
        "nombre": "Juan Pérez",
        "monto": "$1,500.00"
      },
      "current_node_id": null,
      "error_message": null,
      "scheduled_at": null,
      "started_at": "2024-01-20T10:00:00Z",
      "finished_at": "2024-01-20T10:05:30Z",
      "created_at": "2024-01-20T09:59:58Z"
    }
  ],
  "has_more": false,
  "url": "/v1/flows/01234567-89ab-cdef-0123-456789abcdef/runs"
}
GET /api/v1/flows/{flow_id}/runs/{run_id}

Obtiene el detalle de una ejecución específica del flujo.

Respuesta

{
  "object": "flow_run",
  "id": "f1a2b3c4-d5e6-7890-abcd-111111111111",
  "flow_id": "01234567-89ab-cdef-0123-456789abcdef",
  "flow_name": "Flujo de Cobranza",
  "phone_number": "+5215512345678",
  "country_code": "MX",
  "customer_id": "cust-uuid-123",
  "customer_name": "Juan Pérez",
  "conversation_id": "conv-uuid-789",
  "status": "waiting",
  "source": "api",
  "batch_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "context": {
    "nombre": "Juan Pérez",
    "monto": "$1,500.00",
    "respuesta_cliente": "Sí, pagaré mañana"
  },
  "current_node_id": "node_1768811907821_4wexo4g3h",
  "error_message": null,
  "scheduled_at": null,
  "started_at": "2024-01-20T10:00:00Z",
  "finished_at": null,
  "created_at": "2024-01-20T09:59:58Z"
}
POST /api/v1/flows/{flow_id}/runs/{run_id}/variables

Actualiza las variables de una ejecución en curso. Útil para inyectar información externa que será usada en los siguientes nodos del flujo.

Cuerpo de la Petición

{
  "variables": {
    "crm_status": "contacted",
    "agent_notes": "Cliente confirmó pago para mañana",
    "follow_up_date": "2024-01-21"
  }
}
POST /api/v1/flows/{flow_id}/runs/{run_id}/cancel

Cancela una ejecución que está pendiente o en espera. Las ejecuciones completadas o fallidas no pueden cancelarse.

Respuesta

{
  "success": true,
  "message": "Flow run cancelled successfully",
  "data": {
    "id": "f1a2b3c4-d5e6-7890-abcd-111111111111",
    "flow_id": "01234567-89ab-cdef-0123-456789abcdef",
    "flow_name": "Flujo de Cobranza",
    "phone_number": "+5215512345678",
    "country_code": "MX",
    "customer_id": "cust-uuid-123",
    "customer_name": "Juan Pérez",
    "conversation_id": null,
    "status": "cancelled",
    "source": "api",
    "batch_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "context": {
      "nombre": "Juan Pérez"
    },
    "current_node_id": null,
    "error_message": null,
    "scheduled_at": null,
    "started_at": null,
    "finished_at": "2024-01-20T11:00:00Z",
    "created_at": "2024-01-20T09:59:58Z"
  }
}

Webhooks de Conversación

Configura webhooks para recibir notificaciones en tiempo real sobre eventos de conversación y flujos. Los webhooks se configuran desde el panel de Webhook Endpoints.

Eventos Disponibles

Evento Descripción
conversation.created Nueva conversación iniciada
conversation.assigned Conversación asignada a un agente
conversation.transferred Conversación transferida a otro agente o grupo
conversation.resolved Conversación marcada como resuelta
conversation.closed Conversación cerrada con motivo
conversation.message.received Mensaje recibido del cliente
conversation.message.sent Mensaje enviado al cliente
flow_run.started Ejecución de flujo iniciada
flow_run.completed Ejecución de flujo completada
flow_run.failed Ejecución de flujo fallida
flow_run.waiting Flujo esperando respuesta del cliente

Ejemplo de Payload (conversation.message.received)

{
  "id": "evt_123456",
  "type": "conversation.message.received",
  "created_at": "2024-01-20T10:05:30Z",
  "data": {
    "id": "msg_abc123",
    "conversation_id": "conv_xyz789",
    "direction": "inbound",
    "type": "text",
    "body": "Sí, haré el pago mañana",
    "sender_identifier": "+5215512345678",
    "created_at": "2024-01-20T10:05:30Z",
    "conversation": {
      "id": "conv_xyz789",
      "channel": "whatsapp",
      "channel_identifier": "+5215512345678",
      "status": "open",
      "customer_id": "cust_abc",
      "customer_name": "Juan Pérez",
      "assigned_user_id": "user_123",
      "assigned_user_name": "Ana López"
    }
  }
}

Casos de Uso

Campaña de Cobranza Masiva

Despliega un flujo de recordatorio de pago a miles de clientes con variables personalizadas (nombre, monto, fecha). El flujo puede incluir múltiples mensajes, esperas por respuesta, y ramificaciones basadas en las respuestas del cliente.

Integración con CRM

Usa los webhooks para sincronizar el estado de las conversaciones con tu CRM. Cuando un cliente responde, actualiza automáticamente su registro con la respuesta y programa seguimientos.

Encuestas y NPS

Despliega flujos interactivos con botones para recopilar feedback de clientes. Usa las variables del run para almacenar las respuestas y consultar los resultados vía API.

Seguimientos

Programa y gestiona tareas de seguimiento con tus clientes

Listar seguimientos

GET /v1/follow-ups

Retorna una lista paginada de seguimientos. Puedes filtrar por estado, tipo, agente o cliente.

Campo Tipo Requerido Descripción
statusstringNoFiltrar por estado: pending, completed, overdue
typestringNoFiltrar por tipo: call, message, whatsapp, email, meeting, task
user_iduuidNoFiltrar por agente asignado
customer_iduuidNoFiltrar por cliente
limitintegerNoResultados por página (default: 20)
Ejemplo de petición
curl https://recaudo.app/api/v1/follow-ups?status=pending \
  -H "Authorization: Bearer sk_live_tu_secret_key" \
  -H "Content-Type: application/json"
Respuesta
{
  "object": "list",
  "data": [
    {
      "id": "01234567-89ab-cdef-0123-456789abcdef",
      "title": "Llamar para confirmar pago",
      "description": "El cliente solicitó una llamada de seguimiento",
      "status": "pending",
      "type": "call",
      "scheduled_at": "2026-04-10T14:00:00Z",
      "completed_at": null,
      "customer": {
        "id": "uuid-del-cliente",
        "name": "Juan Pérez",
        "phone": "+5215512345678"
      },
      "user": {
        "id": "uuid-del-agente",
        "name": "María López"
      },
      "created_at": "2026-04-08T10:00:00Z",
      "updated_at": "2026-04-08T10:00:00Z"
    }
  ],
  "total": 15
}

Crear seguimiento

POST /v1/follow-ups
Campo Tipo Requerido Descripción
titlestringTítulo del seguimiento (máx 255 chars)
descriptionstringNoDescripción o notas adicionales
customer_iduuidNoUUID del cliente asociado
conversation_iduuidNoUUID de la conversación asociada
user_iduuidNoUUID del agente asignado
scheduled_atdatetimeFecha y hora programada (ISO 8601)
typestringNocall, message, whatsapp, email, meeting, task
Ejemplo de petición
curl -X POST https://recaudo.app/api/v1/follow-ups \
  -H "Authorization: Bearer sk_live_tu_secret_key" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Llamar para confirmar pago",
    "description": "El cliente pidió que le llamemos el jueves",
    "customer_id": "uuid-del-cliente",
    "user_id": "uuid-del-agente",
    "scheduled_at": "2026-04-10T14:00:00Z",
    "type": "call"
  }'
Respuesta — 201 Created
{
  "object": "follow_up",
  "data": {
    "id": "01234567-89ab-cdef-0123-456789abcdef",
    "title": "Llamar para confirmar pago",
    "description": "El cliente pidió que le llamemos el jueves",
    "status": "pending",
    "type": "call",
    "scheduled_at": "2026-04-10T14:00:00Z",
    "completed_at": null,
    "customer": {
      "id": "uuid-del-cliente",
      "name": "Juan Pérez"
    },
    "user": {
      "id": "uuid-del-agente",
      "name": "María López"
    },
    "created_at": "2026-04-08T10:00:00Z"
  }
}

Completar seguimiento

POST /v1/follow-ups/{'{id}'}/complete

Marca un seguimiento como completado. Opcionalmente puedes agregar notas.

Campo Tipo Requerido Descripción
notesstringNoNotas sobre la resolución
Ejemplo de petición
curl -X POST https://recaudo.app/api/v1/follow-ups/{id}/complete \
  -H "Authorization: Bearer sk_live_tu_secret_key" \
  -H "Content-Type: application/json" \
  -d '{ "notes": "Cliente confirmó que realizará el pago mañana" }'
Respuesta
{
  "object": "follow_up",
  "data": {
    "id": "01234567-89ab-cdef-0123-456789abcdef",
    "title": "Llamar para confirmar pago",
    "status": "completed",
    "completed_at": "2026-04-08T15:30:00Z",
    "notes": "Cliente confirmó que realizará el pago mañana"
  }
}

Reprogramar seguimiento

POST /v1/follow-ups/{'{id}'}/reschedule

Cambia la fecha programada de un seguimiento pendiente.

Campo Tipo Requerido Descripción
scheduled_atdatetimeNueva fecha y hora programada (ISO 8601)
Ejemplo de petición
curl -X POST https://recaudo.app/api/v1/follow-ups/{id}/reschedule \
  -H "Authorization: Bearer sk_live_tu_secret_key" \
  -H "Content-Type: application/json" \
  -d '{ "scheduled_at": "2026-04-12T10:00:00Z" }'
Respuesta
{
  "object": "follow_up",
  "data": {
    "id": "01234567-89ab-cdef-0123-456789abcdef",
    "title": "Llamar para confirmar pago",
    "status": "pending",
    "scheduled_at": "2026-04-12T10:00:00Z"
  }
}

Templates de WhatsApp

Consulta los templates aprobados disponibles para envío

Listar templates

GET /v1/whatsapp-templates

Retorna todos los templates de WhatsApp configurados para tu cuenta. Incluye el estado de aprobación de Meta.

Ejemplo de petición
curl https://recaudo.app/api/v1/whatsapp-templates \
  -H "Authorization: Bearer sk_live_tu_secret_key" \
  -H "Content-Type: application/json"
Respuesta
{
  "object": "list",
  "data": [
    {
      "id": "01234567-89ab-cdef-0123-456789abcdef",
      "name": "recordatorio_pago",
      "description": "Recordatorio de pago pendiente",
      "content_type": "text",
      "variables": ["nombre", "monto", "fecha_limite"],
      "meta_template_status": "APPROVED"
    },
    {
      "id": "98765432-10fe-dcba-9876-543210fedcba",
      "name": "confirmacion_pedido",
      "description": "Confirmación de pedido realizado",
      "content_type": "text",
      "variables": ["nombre", "numero_pedido"],
      "meta_template_status": "APPROVED"
    }
  ]
}

Los templates deben estar aprobados por Meta (meta_template_status: "APPROVED") para poder ser enviados.

Mensajes Interactivos

Envía mensajes con botones o listas de opciones por WhatsApp

Enviar mensaje interactivo

POST /v1/conversations/{'{id}'}/interactive

Envía un mensaje interactivo de WhatsApp con botones de respuesta rápida o una lista de opciones. Solo disponible para conversaciones de WhatsApp.

Campo Tipo Requerido Descripción
typestringTipo de mensaje: buttons o list
bodystringTexto del mensaje (máx 1024 chars)
buttonsarraySí*Botones de respuesta (mín 1, máx 3). Requerido si type=buttons
buttons.*.titlestringTexto del botón (máx 20 chars)
sectionsarraySí*Secciones de la lista. Requerido si type=list
sections.*.titlestringNoTítulo de la sección (máx 24 chars)
sections.*.rowsarrayOpciones de la sección (mín 1, máx 10)
sections.*.rows.*.titlestringTexto de la opción (máx 24 chars)
sections.*.rows.*.descriptionstringNoDescripción de la opción (máx 72 chars)
button_textstringNoTexto del botón de la lista (default: "Seleccionar", máx 20 chars)

* buttons es requerido cuando type=buttons. sections es requerido cuando type=list.

Ejemplo — Mensaje con botones
curl -X POST https://recaudo.app/api/v1/conversations/{id}/interactive \
  -H "Authorization: Bearer sk_live_tu_secret_key" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "buttons",
    "body": "¿Deseas confirmar tu pago de $1,500.00?",
    "buttons": [
      { "title": "Sí, confirmar" },
      { "title": "No, cancelar" },
      { "title": "Hablar con agente" }
    ]
  }'
Ejemplo — Mensaje con lista
curl -X POST https://recaudo.app/api/v1/conversations/{id}/interactive \
  -H "Authorization: Bearer sk_live_tu_secret_key" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "list",
    "body": "Selecciona el método de pago que prefieres:",
    "button_text": "Ver opciones",
    "sections": [
      {
        "title": "Métodos de pago",
        "rows": [
          { "title": "Tarjeta de crédito", "description": "Visa, Mastercard, AMEX" },
          { "title": "Transferencia SPEI", "description": "Pago inmediato desde tu banco" },
          { "title": "Pago en OXXO", "description": "Genera una referencia de pago" }
        ]
      }
    ]
  }'
Respuesta
{
  "object": "message",
  "data": {
    "id": "01234567-89ab-cdef-0123-456789abcdef",
    "conversation_id": "uuid-de-la-conversacion",
    "type": "interactive",
    "direction": "outbound",
    "status": "sent",
    "created_at": "2026-04-08T10:30:00Z"
  }
}

Asignar Conversación

Asigna conversaciones a agentes humanos de tu equipo

Asignar agente

POST /v1/conversations/{'{id}'}/assign

Asigna una conversación a un miembro de tu equipo. Al asignar, la conversación se marca como manejada por un humano y se desactiva el agente de IA.

Campo Tipo Requerido Descripción
user_iduuidNoUUID del miembro del equipo. Usa GET /v1/team para obtener los IDs disponibles
Ejemplo de petición
curl -X POST https://recaudo.app/api/v1/conversations/{id}/assign \
  -H "Authorization: Bearer sk_live_tu_secret_key" \
  -H "Content-Type: application/json" \
  -d '{ "user_id": "uuid-del-agente" }'
Respuesta
{
  "object": "conversation",
  "data": {
    "id": "uuid-de-la-conversacion",
    "channel": "whatsapp",
    "status": "open",
    "is_handled_by_ai": false,
    "assigned_user": {
      "id": "uuid-del-agente",
      "name": "María López"
    },
    "customer": {
      "id": "uuid-del-cliente",
      "name": "Juan Pérez",
      "phone": "+5215512345678"
    },
    "updated_at": "2026-04-08T10:30:00Z"
  }
}

Equipo

Consulta los miembros activos de tu equipo

Listar miembros del equipo

GET /v1/team

Retorna todos los miembros activos de tu equipo. Útil para obtener IDs de agentes al asignar conversaciones o seguimientos.

Ejemplo de petición
curl https://recaudo.app/api/v1/team \
  -H "Authorization: Bearer sk_live_tu_secret_key" \
  -H "Content-Type: application/json"
Respuesta
{
  "object": "list",
  "data": [
    {
      "id": "01234567-89ab-cdef-0123-456789abcdef",
      "name": "María López",
      "email": "maria@empresa.com",
      "phone": "+5215512345678",
      "job_title": "Gerente de Cobranza",
      "status": "active"
    },
    {
      "id": "98765432-10fe-dcba-9876-543210fedcba",
      "name": "Carlos Ramírez",
      "email": "carlos@empresa.com",
      "phone": "+5215598765432",
      "job_title": "Agente de Soporte",
      "status": "active"
    }
  ]
}

Fuentes de Clientes

Consulta las fuentes de adquisición configuradas para tus clientes

Listar fuentes de clientes

GET /v1/customer-sources

Retorna todas las fuentes de adquisición de clientes configuradas. Útil para asignar una fuente al crear o actualizar clientes.

Ejemplo de petición
curl https://recaudo.app/api/v1/customer-sources \
  -H "Authorization: Bearer sk_live_tu_secret_key" \
  -H "Content-Type: application/json"
Respuesta
{
  "object": "list",
  "data": [
    {
      "id": "01234567-89ab-cdef-0123-456789abcdef",
      "name": "Sitio Web",
      "slug": "sitio-web"
    },
    {
      "id": "98765432-10fe-dcba-9876-543210fedcba",
      "name": "Referido",
      "slug": "referido"
    },
    {
      "id": "abcdef01-2345-6789-abcd-ef0123456789",
      "name": "Facebook Ads",
      "slug": "facebook-ads"
    }
  ]
}