Documentación
API y MCP de Lidra SMM
Todo lo que hacés desde la web, desde tu código o desde un asistente de inteligencia artificial. Activá el modo desarrollador en Mi cuenta y creá tu primera API key.
Introducción
Lidra SMM es una plataforma argentina de marketing en redes sociales. Esta documentación cubre las tres formas de usarla desde afuera del navegador, todas con la misma API key y los mismos permisos.
- API REST (
/api/v1): JSON moderno, códigos HTTP de verdad. Es la que conviene si estás escribiendo algo nuevo. - Endpoint compatible (
/api/v2): habla el formato estándar de los paneles SMM. Si ya tenés software que integra un panel, apuntalo a Lidra cambiando la URL base y la key. - Servidor MCP (
/api/mcp): conecta un asistente de inteligencia artificial —Claude, ChatGPT o el que uses— para que opere tu cuenta hablándole en castellano.
Las tres exponen las mismas 24 operaciones. Todo lo que podés hacer desde la web, podés hacerlo desde acá.
Empezar en tres pasos
- 1Entrá a Mi cuenta y activá el Modo desarrollador.
- 2Andá a Desarrollador y creá una API key. Se muestra una sola vez: copiala.
- 3Probala. Si responde, ya está.
curl https://lidra.com.ar/api/v1/status \
-H "Authorization: Bearer lidra_sk_TU_API_KEY"{
"ok": true,
"apiVersion": "v1",
"surface": "rest",
"scopes": ["catalog:read", "orders:read", "orders:write", "..."],
"serverTime": "2026-07-09T14:32:10.000Z"
}Un flujo completo, de un link a un pedido: analizás el link, cotizás, y recién ahí comprás.
# 1. ¿Qué se le puede comprar a este link?
curl "https://lidra.com.ar/api/v1/links/services?url=https://instagram.com/p/ABC123" \
-H "Authorization: Bearer $LIDRA_KEY"
# 2. ¿Cuánto sale? (no cobra nada)
curl -X POST https://lidra.com.ar/api/v1/quotes \
-H "Authorization: Bearer $LIDRA_KEY" \
-H "Content-Type: application/json" \
-d '{"serviceId":"svc_a1b2c3d4e5f6a7b8","quantity":1000}'
# 3. Comprar (esto SÍ cobra tu saldo)
curl -X POST https://lidra.com.ar/api/v1/orders \
-H "Authorization: Bearer $LIDRA_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: mi-pedido-0001" \
-d '{"serviceId":"svc_a1b2c3d4e5f6a7b8","link":"https://instagram.com/p/ABC123","quantity":1000}'Autenticación
Toda petición lleva tu API key en el header Authorization. En el endpoint compatible va como campo key del cuerpo, porque así lo define ese formato.
Authorization: Bearer lidra_sk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxLa key nunca se lee de una cookie. Eso significa que un sitio hostil no puede hacer peticiones a la API en tu nombre aunque tengas la sesión de Lidra abierta.
Formato. lidra_sk_ seguido de 32 caracteres. El prefijo sirve para reconocerla de un vistazo y para que los detectores de secretos la marquen si se filtra.
Se muestra una sola vez. Al crearla, y al rotarla. Después no la tiene nadie: en nuestra base solo queda un hash SHA-256, que no se puede revertir. Ni el equipo de Lidra puede leer tu key. Si la perdés, rotala.
Rotación. Rotar una key le cambia el secreto en el lugar: te damos uno nuevo y el anterior deja de funcionar en el acto. El nombre, los permisos y el identificador de la key se mantienen. Rotá cuando sospeches una filtración, cuando se vaya alguien del equipo, o cada tanto por higiene.
Vencimiento. Al crear la key elegís 30, 90 o 365 días, o ninguno. Una key sin vencimiento es una key que nunca se rota: si la integración va a durar, ponele fecha.
Revocar y eliminar. Revocar la mata para siempre. Eliminar borra además su registro. Podés tener hasta 10 keys activas a la vez; una por integración es una buena idea, porque te deja revocar solo la comprometida.
Permisos (scopes). Cada key lleva la lista de lo que puede hacer. Una petición sin el permiso necesario devuelve 403 insufficient_scope. Dale a cada key el mínimo que necesite: si tu bot solo mira pedidos, no le des orders:write.
| Permiso | Qué habilita | Detalle |
|---|---|---|
catalog:read | Ver el catálogo | Buscar servicios, analizar links y cotizar pedidos. |
orders:read | Ver pedidos | Listar tus pedidos y consultar su avance. |
orders:write | Crear y modificar pedidos | Hacer pedidos nuevos (gasta tu saldo), cancelar y pedir reposición. |
wallet:read | Ver la billetera | Consultar tu saldo y tus movimientos. |
wallet:topup | Generar recargas | Crear un link de pago de Mercado Pago para cargar saldo. |
clients:read | Ver clientes | Listar tus clientes y carpetas del CRM. |
clients:write | Crear clientes | Agregar clientes y carpetas al CRM. |
tickets:read | Ver soporte | Listar tus consultas de soporte y sus respuestas. |
tickets:write | Escribir a soporte | Abrir consultas nuevas y responder las existentes. |
profile:read | Ver tu perfil | Consultar tu email, nombre y saldo. |
Convenciones
Dinero. Todos los montos son enteros en centavos de pesos argentinos. 208000 son $2.080,00. Nunca hay decimales ni números en coma flotante, así que no hay errores de redondeo. Los campos que llevan plata terminan en ArsCents.
Excepción. El endpoint compatible (/api/v2) usa pesos como texto decimal ("2080.0000"), porque es lo que ese formato define y lo que sus clientes esperan.
Fechas. Siempre ISO 8601 en UTC: 2026-07-09T14:32:10.000Z.
Identificadores. Los servicios usan un id opaco que empieza con svc_. Los pedidos, clientes y consultas usan UUID. Son estables: guardalos.
Paginación. Los listados aceptan limit (hasta 100) y offset, y devuelven total y hasMore.
Idempotencia. POST /api/v1/orders acepta el header Idempotency-Key. Si reintentás con la misma clave, te devolvemos el pedido original en vez de crear otro y cobrarte dos veces. Usá una clave distinta por pedido y guardala antes de llamar. Reintentar con la misma clave y un cuerpo distinto devuelve el pedido original: la clave manda.
Estados de pedido. Un pedido nace en pending y avanza solo. No hace falta reintentar nada: si el despacho falla, lo reintentamos por vos.
| Estado | En pantalla | Qué significa |
|---|---|---|
pending | Pendiente | Cobrado y en cola. Todavía no empezó a entregarse. |
processing | En progreso | Entregándose. |
completed | Completado | Entregado por completo. |
partial | Entrega parcial | Se entregó una parte. La diferencia se reintegró al saldo. |
canceled | Cancelado | Cancelado. El saldo se reintegró. |
refunded | Reembolsado | Reembolsado por completo. |
failed | Fallido | No se pudo procesar. El saldo se reintegró. |
Cómo seguir un pedido. Consultá GET /api/v1/orders/{orderId}. Si seguís muchos, usá POST /api/v1/orders/status con hasta 100 ids en una sola petición: es lo que corresponde y no te come el límite. Consultar cada 30 segundos mientras haya pedidos activos alcanza y sobra.
Límites
| Qué | Límite |
|---|---|
| Peticiones por API key | 240 por minuto |
| Creación de pedidos | 30 por minuto |
| Pedidos por consulta de estado en lote | 100 |
| Resultados por página | 100 |
| API keys activas por cuenta | 10 |
| Recarga mínima | 50.000 centavos ($500) |
| Recarga máxima | 100.000.000 centavos ($1.000.000) |
Cada respuesta trae X-RateLimit-Limit, X-RateLimit-Remaining y X-RateLimit-Reset. Si te pasás, devolvemos 429 con Retry-After en segundos: esperá eso y reintentá.
Errores
La API REST usa códigos HTTP y siempre devuelve el mismo cuerpo:
{
"error": {
"code": "insufficient_funds",
"message": "Saldo insuficiente. Cargá créditos antes de hacer el pedido.",
"docs": "https://lidra.com.ar/desarrolladores#errores"
}
}| Código | HTTP | Qué pasó |
|---|---|---|
unauthorized | 401 | No mandaste la API key. |
invalid_key | 401 | La key no existe o está mal escrita. |
key_revoked | 401 | La key fue revocada. |
key_expired | 401 | La key venció. |
developer_mode_disabled | 403 | El modo desarrollador está apagado. Activalo en Mi cuenta. |
insufficient_scope | 403 | La key no tiene el permiso que esa operación necesita. |
rate_limited | 429 | Demasiadas peticiones. Mirá Retry-After. |
validation_error | 400 | Un parámetro falta o está mal. El detalle dice cuál. |
quantity_out_of_range | 400 | La cantidad está fuera del mínimo o el máximo del servicio. |
not_found | 404 | El recurso no existe, o no es tuyo. |
feature_disabled | 404 | Esa función no está habilitada. |
insufficient_funds | 402 | No te alcanza el saldo. Usá create_topup. |
service_unavailable | 409 | El servicio no se puede comprar ahora mismo. |
order_not_cancelable | 409 | El pedido ya arrancó a entregarse. |
refill_not_available | 409 | Ese pedido no admite reposición, o ya la pediste. |
temporarily_unavailable | 503 | Problema temporal. Reintentá en unos minutos. |
internal_error | 500 | Error nuestro. Si se repite, escribinos. |
not_found también aparece cuando pedís algo que existe pero es de otra cuenta. Es a propósito: no confirmamos la existencia de recursos ajenos.Referencia de la API REST
Base: https://lidra.com.ar/api/v1. Todas las peticiones necesitan el header Authorization.
| Endpoint | Qué hace | Permiso | Tool MCP equivalente |
|---|---|---|---|
POST /api/v1/links/detect | Analizar un link | catalog:read | detect_link |
GET /api/v1/links/services | Servicios compatibles con un link | catalog:read | services_for_link |
GET /api/v1/services | Buscar servicios | catalog:read | search_services |
GET /api/v1/services/{serviceId} | Ver un servicio | catalog:read | get_service |
POST /api/v1/quotes | Cotizar un pedido | catalog:read | quote_order |
POST /api/v1/orders | Crear un pedido | orders:write | create_order |
GET /api/v1/orders | Listar pedidos | orders:read | list_orders |
GET /api/v1/orders/{orderId} | Ver un pedido | orders:read | get_order |
POST /api/v1/orders/status | Estado de varios pedidos | orders:read | get_orders_status |
POST /api/v1/orders/{orderId}/cancel | Cancelar un pedido | orders:write | cancel_order |
POST /api/v1/orders/{orderId}/refill | Pedir reposición | orders:write | request_refill |
GET /api/v1/orders/{orderId}/refill | Estado de la reposición | orders:read | get_refill_status |
GET /api/v1/wallet | Ver el saldo | wallet:read | get_balance |
GET /api/v1/wallet/transactions | Listar movimientos | wallet:read | list_transactions |
POST /api/v1/wallet/topups | Generar una recarga | wallet:topup | create_topup |
GET /api/v1/clients | Listar clientes | clients:read | list_clients |
POST /api/v1/clients | Crear un cliente | clients:write | create_client |
GET /api/v1/folders | Listar carpetas | clients:read | list_folders |
POST /api/v1/folders | Crear una carpeta | clients:write | create_folder |
GET /api/v1/tickets | Listar consultas de soporte | tickets:read | list_tickets |
POST /api/v1/tickets | Abrir una consulta de soporte | tickets:write | create_ticket |
POST /api/v1/tickets/{ticketId}/replies | Responder una consulta | tickets:write | reply_ticket |
GET /api/v1/me | Ver tu perfil | profile:read | get_profile |
GET /api/v1/status | Estado de la API | — | get_api_status |
Los parámetros de cada operación están en la tabla de herramientas MCP más abajo: son exactamente los mismos. En GET van en el query string, en POST en el cuerpo JSON.
El esquema completo, con tipos y validaciones, está publicado en formato OpenAPI 3.1:
curl https://lidra.com.ar/api/openapi.jsonServidor MCP
MCP (Model Context Protocol) es el estándar que usan los asistentes de inteligencia artificial para conectarse a servicios externos. Conectando Lidra por MCP, tu asistente puede buscar servicios, cotizar, ver tu saldo y hacer pedidos, hablándole en castellano.
No hay nada que instalar: el servidor vive en https://lidra.com.ar/api/mcp y se autentica con tu misma API key.
Claude Code, una línea en la terminal:
claude mcp add --transport http lidra https://lidra.com.ar/api/mcp \
--header "Authorization: Bearer lidra_sk_TU_API_KEY"Claude Desktop y otros clientes, en el archivo de configuración:
{
"mcpServers": {
"lidra": {
"type": "http",
"url": "https://lidra.com.ar/api/mcp",
"headers": {
"Authorization": "Bearer lidra_sk_TU_API_KEY"
}
}
}
}Detalles del transporte, por si estás escribiendo un cliente: Streamable HTTP sin estado. POST con un mensaje JSON-RPC 2.0 y respuesta application/json (no abrimos stream SSE). Las notificaciones se contestan con 202. GET y DELETE devuelven 405. No emitimos Mcp-Session-Id. Versiones de protocolo soportadas: 2025-11-25, 2025-06-18, 2025-03-26.
Métodos: initialize, ping, tools/list, tools/call, resources/list, resources/read, prompts/list, prompts/get.
Cada herramienta devuelve un resumen en castellano en content y el JSON completo en structuredContent. Un error de negocio (saldo insuficiente, pedido no cancelable) vuelve como isError: true con la explicación, no como un error de protocolo.
Recursos: lidra://catalogo/taxonomia (todos los valores válidos) y lidra://cuenta/permisos (qué puede hacer tu key).
Prompts: comprar, revisar_pedidos y diagnosticar_pedido, que guían al asistente por el flujo correcto.
create_order gasta plata real: el prompt comprar está escrito para que el asistente te pida confirmación antes.Agente A2A
A2A (Agent2Agent) es el otro lado de la moneda del MCP: en MCP tu asistente usa las herramientas de Lidra; en A2A, tu agente le habla al agente de Lidra y este le contesta.
El agente vive en https://lidra.com.ar/api/a2a y su tarjeta —qué sabe hacer y cómo hablarle— en https://lidra.com.ar/.well-known/agent-card.json. Se autentica con la misma API key.
Hace tres cosas y nada más. Si le mandás un link, te dice qué se le puede comprar y a cuánto. Si le mandás una habilidad con sus datos, la ejecuta. Si no le mandás ninguna de las dos, te dice qué sabe hacer. No hay un modelo de lenguaje adentro: es determinístico, y por eso no le pidas que interprete una consigna libre.
Pasarle un link (lo más común):
curl -X POST https://lidra.com.ar/api/a2a \
-H "Authorization: Bearer $LIDRA_KEY" \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0", "id": 1, "method": "message/send",
"params": {
"message": {
"kind": "message", "messageId": "m1", "role": "user",
"parts": [{ "kind": "text", "text": "https://instagram.com/p/ABC123" }]
}
}
}'Ejecutar una habilidad concreta, con una parte de datos:
{
"kind": "message", "messageId": "m2", "role": "user",
"parts": [{
"kind": "data",
"data": { "skill": "quote_order", "input": { "serviceId": "svc_a1b2c3d4e5f6a7b8", "quantity": 1000 } }
}]
}La respuesta es siempre un Message del agente con dos partes: una de texto con el resumen en castellano, y una de datos con el JSON completo. No hay tareas de larga duración: tasks/get, message/stream y los avisos por webhook devuelven el error que corresponde en vez de dejarte esperando. La tarjeta lo declara en capabilities.
Las habilidades son las mismas 24 operaciones de la tabla de abajo, con los mismos permisos y los mismos límites. Un error de negocio (saldo insuficiente, permiso faltante) vuelve dentro del mensaje, no como error de protocolo.
Herramientas y parámetros
Las 24 operaciones, con sus parámetros. Los marcados con * son obligatorios. Valen igual para la API REST: son los mismos nombres.
| Nombre | Qué hace | Parámetros | Permiso |
|---|---|---|---|
detect_link | Lee un link de red social y devuelve de qué plataforma es, qué tipo de contenido, y qué métricas se le pueden comprar. Primer paso natural antes de buscar servicios. | url* | catalog:read |
services_for_link | Dado un link, devuelve todos los servicios que se le pueden aplicar, con el precio del día en pesos. Es la forma más rápida de pasar de un link a algo comprable. | url* | catalog:read |
search_services | Busca en el catálogo por plataforma, métrica, tipo de contenido o nombre. Devuelve el precio final en centavos de ARS por cada 1000 unidades. | platform, metric, contentType, query, limit, offset | catalog:read |
get_service | Devuelve el detalle de un servicio: precio, mínimo, máximo y si admite reposición o entrega gradual. | serviceId* | catalog:read |
quote_order | Calcula cuánto costaría un pedido sin crearlo ni cobrar nada. Usalo siempre antes de create_order para confirmarle el precio a la persona. | serviceId*, quantity*, runs, intervalMinutes | catalog:read |
create_order | Crea un pedido y COBRA el saldo de la billetera al instante. Confirmá el precio con quote_order antes de llamar a esto. El pedido vuelve en estado pending; el avance se consulta con get_order. | serviceId*, link*, quantity*, runs, intervalMinutes, comments, clientId, resellPriceArsCents, idempotencyKey | orders:write |
list_orders | Devuelve tus pedidos, con filtros por estado, plataforma o cliente. | status, platform, clientId, limit, offset | orders:read |
get_order | Devuelve un pedido con su estado, lo entregado y lo que falta. | orderId* | orders:read |
get_orders_status | Consulta hasta 100 pedidos de una sola vez. Es la forma correcta de seguir el avance de muchos pedidos sin gastar el límite de peticiones. | orderIds* | orders:read |
cancel_order | Cancela un pedido que todavía no empezó a entregarse y reintegra el saldo. Si la entrega ya arrancó, no se puede: hay que abrir una consulta de soporte. | orderId* | orders:write |
request_refill | Pide la reposición de un pedido completado, si el servicio la admite (por ejemplo, seguidores que se cayeron). Se puede pedir una sola vez por pedido. | orderId* | orders:write |
get_refill_status | Devuelve si la reposición de un pedido está pedida, en curso, completada o rechazada. | orderId* | orders:read |
get_balance | Devuelve el saldo disponible en la billetera, en centavos de ARS. | — | wallet:read |
list_transactions | Devuelve los movimientos de la billetera: recargas, cobros de pedidos, reintegros y ajustes. | limit | wallet:read |
create_topup | Crea un link de pago de Mercado Pago para cargar saldo. Devuelve la URL; el saldo se acredita recién cuando el pago se aprueba. | amountArsCents* | wallet:topup |
list_clients | Devuelve los clientes de tu CRM, con cuántos pedidos hizo cada uno y cuánto gastó. | — | clients:read |
create_client | Agrega un cliente a tu CRM para imputarle pedidos. | name*, folderId, handle, notes | clients:write |
list_folders | Devuelve las carpetas con las que organizás tus clientes. | — | clients:read |
create_folder | Crea una carpeta para agrupar clientes. | name* | clients:write |
list_tickets | Devuelve tus consultas de soporte con todos sus mensajes. | — | tickets:read |
create_ticket | Abre una consulta de soporte, opcionalmente asociada a un pedido. | subject*, body*, orderId | tickets:write |
reply_ticket | Agrega un mensaje tuyo a una consulta existente. Si estaba cerrada, se reabre. | ticketId*, body* | tickets:write |
get_profile | Devuelve tu email, tu nombre y tu saldo. | — | profile:read |
get_api_status | Confirma que la API key funciona y devuelve qué permisos tiene. No necesita ningún permiso. | — | — |
Endpoint compatible
POST https://lidra.com.ar/api/v2 habla el formato estándar de la industria de paneles SMM. Si ya tenés software que integra un panel, apuntalo acá: solo cambia la URL base y la key.
Los parámetros van como application/x-www-form-urlencoded (también aceptamos JSON), con key y action.
curl -X POST https://lidra.com.ar/api/v2 \
-d "key=lidra_sk_TU_API_KEY" \
-d "action=balance"
# {"balance":"12500.0000","currency":"ARS"}action | Parámetros | Respuesta |
|---|---|---|
services | — | Lista completa de servicios. |
add | service, link, quantity, y opcionales runs, interval, comments | { "order": "<id>" } |
status | order (uno) u orders (hasta 100, separados por coma) | { charge, start_count, status, remains, currency }, o un objeto por id. |
balance | — | { "balance": "1234.5600", "currency": "ARS" } |
refill | order u orders | { "refill": "<id del pedido>" } |
refill_status | refill (el id del pedido) | { "status": "..." } |
cancel | order u orders | Un objeto por pedido con cancel. |
Los montos van en pesos como texto decimal, con currency: "ARS". Los estados son Pending, In progress, Completed, Partial, Canceled y Refunded.
Recetas
Comprar sin sorpresas. Cotizá antes, y usá una clave de idempotencia.
const base = "https://lidra.com.ar/api/v1";
const headers = {
Authorization: `Bearer ${process.env.LIDRA_KEY}`,
"Content-Type": "application/json",
};
// 1. Cotizar. No cobra nada.
const quote = await fetch(`${base}/quotes`, {
method: "POST",
headers,
body: JSON.stringify({ serviceId, quantity: 1000 }),
}).then((r) => r.json());
// 2. ¿Alcanza el saldo?
const { balanceArsCents } = await fetch(`${base}/wallet`, { headers }).then((r) => r.json());
if (balanceArsCents < quote.totalArsCents) {
const topup = await fetch(`${base}/wallet/topups`, {
method: "POST",
headers,
body: JSON.stringify({ amountArsCents: quote.totalArsCents - balanceArsCents }),
}).then((r) => r.json());
throw new Error(`Cargá saldo acá: ${topup.checkoutUrl}`);
}
// 3. Comprar. La clave de idempotencia hace que un reintento no duplique el cobro.
const order = await fetch(`${base}/orders`, {
method: "POST",
headers: { ...headers, "Idempotency-Key": `pedido-${miId}` },
body: JSON.stringify({ serviceId, link, quantity: 1000 }),
}).then((r) => r.json());Seguir muchos pedidos. Una sola petición para hasta 100.
const { orders } = await fetch(`${base}/orders/status`, {
method: "POST",
headers,
body: JSON.stringify({ orderIds: misIds }),
}).then((r) => r.json());
const activos = orders.filter((o) => o.status === "pending" || o.status === "processing");
// Volvé a consultar en 30 segundos mientras queden activos.Reintentar bien. Ante 429, esperá lo que diga Retry-After. Ante 5xx, reintentá con espera creciente. Ante 4xx, no reintentes: arreglá la petición.
async function conReintento(fn, intentos = 4) {
for (let i = 0; i < intentos; i++) {
const res = await fn();
if (res.status === 429) {
const esperar = Number(res.headers.get("retry-after") ?? 1);
await new Promise((r) => setTimeout(r, esperar * 1000));
continue;
}
if (res.status >= 500 && i < intentos - 1) {
await new Promise((r) => setTimeout(r, 2 ** i * 1000));
continue;
}
return res;
}
throw new Error("Se agotaron los reintentos.");
}Buenas prácticas
- Una key por integración. Si una se filtra, revocás esa sola.
- El mínimo de permisos. Si tu bot solo consulta, no le des
orders:write. - La key vive en el servidor. Nunca en el navegador, en una app móvil ni en un repositorio.
- Ponele vencimiento y rotala. Rotar es un botón y no te cambia el nombre ni los permisos.
- Guardá la clave de idempotencia antes de llamar a
create_order, no después. - Si algo se puso raro, apagá el Modo desarrollador: corta todo al instante y no perdés nada.
Versionado
/api/v1 es la versión estable. Vamos a agregar campos y operaciones sin avisar, así que tu código tiene que ignorar los campos que no conozca. Si alguna vez tenemos que romper algo, va a ser en una ruta nueva (/api/v2/... no cuenta: eso es el endpoint compatible, que es otra cosa y no va a cambiar).
Para el MCP, la negociación de versión del protocolo la hace el cliente en initialize. Soportamos 2025-11-25, 2025-06-18, 2025-03-26.
¿Dudas o algo roto? Escribinos a soporte@lidra.com.ar, o abrí una consulta desde la app (o con create_ticket, que para eso está).