API para revendedores

Una API para pedidos, billetera y marketplace

Crea pedidos, sigue la entrega, consulta saldos y gestiona anuncios desde tu propio sistema. Endpoints REST versionados, claves con alcances, escrituras idempotentes y webhooks firmados, sobre el mismo motor que mueve esta tienda.

  • REST /v1, JSON de entrada y salida
  • Claves Bearer con alcances
  • Idempotency-Key en las escrituras
  • Webhooks firmados
  • Plan Revendedor

Cómo funciona una integración

Cinco llamadas desde cero hasta un pedido entregado

La API refleja lo que hace el panel, en el mismo orden. No se cobra nada hasta que creas un pedido, y toda escritura es idempotente.

  1. Crea una clave

    En tu panel, elige los alcances que necesita la clave y, si quieres, las IP autorizadas a usarla. La clave completa se muestra una sola vez.

  2. Lee el catálogo

    GET /v1/catalog/services devuelve todos los servicios publicados con el precio ya en la moneda y el nivel de tu cuenta.

  3. Previsualiza la cotización

    POST /v1/orders/preview valida el enlace y la cantidad y devuelve el cargo exacto sin crear nada.

  4. Crea el pedido

    POST /v1/orders con un Idempotency-Key. Se debita la billetera y el pedido se enruta al proveedor con la mejor calidad medida.

  5. Escucha los eventos

    Registra un endpoint https y recibe eventos firmados de cambios de estado, entrega parcial, finalización, reembolsos y refills.

Crea un pedido en una sola solicitudbash
curl -X POST https://YOUR-DOMAIN/v1/orders \
  -H "Authorization: Bearer smp_live_xxxxxxxxxx_..." \
  -H "Idempotency-Key: 2b7c1d9e-order-1001" \
  -H "Content-Type: application/json" \
  -d '{"service":"<service_id>","link":"https://instagram.com/p/abc","quantity":1000}'

Reemplaza YOUR-DOMAIN por el host de esta tienda, la clave por la tuya y <service_id> por un id del catálogo.

Autenticación y límites

Claves con alcance, restricción y rotación

La clave es una credencial de servidor. Nunca va al navegador, lleva solo los permisos que concedes y puedes revocarla o rotarla en cualquier momento sin tocar tus otras claves.

Claves Bearer

Envía Authorization: Bearer smp_live_… o X-Api-Key. La clave completa se muestra una vez y solo se guarda su hash. Hasta 20 claves activas por cuenta, vencimiento opcional y rotación con un clic.

Lista de IP permitidas

Opcionalmente, fija la clave a hasta 20 direcciones IP. Las solicitudes desde cualquier otra dirección se rechazan con 403 FORBIDDEN.

Límite por clave

Cada clave hereda el límite de solicitudes por minuto de tu nivel de cliente. Cada respuesta incluye RateLimit-Limit, RateLimit-Remaining y RateLimit-Reset; por encima del límite recibes 429 con Retry-After.

Límite vigente para el nivel Revendedor1,200 solicitudes por minuto

Alcances

Cada clave lleva solo los alcances que concedes. Una llamada fuera de sus alcances se rechaza con 403 FORBIDDEN.

AlcanceQué hace
catalog:readListar servicios y precios
orders:readConsultar pedidos
orders:writeCrear pedidos, refill y cancelación
wallet:readConsultar saldos
assets:readListar tus anuncios y ofertas
assets:writeCrear y editar anuncios, verificación y disponibilidad
transactions:writeRegistrar pasos del traspaso en las operaciones

En cada respuesta

  • X-Request-Id: cítalo cuando contactes a soporte
  • X-Api-Version: la fecha del contrato con el que estás hablando
  • Cache-Control: no-store, las respuestas nunca se almacenan en caché

Idempotencia

Reintenta con seguridad, nunca cobres dos veces

POST /v1/orders y POST /v1/orders/batch exigen el encabezado Idempotency-Key de 8 a 120 caracteres. Repetir una llamada con la misma clave devuelve el mismo pedido sin volver a cobrar. Reutilizar la clave con otro cuerpo se rechaza con 409 IDEMPOTENCY_KEY_REUSE. Dentro de un lote, cada elemento se identifica por la clave del lote más su índice.

  • Genera una clave por pedido lógico (un UUID es ideal) y guárdala antes de enviar.
  • Ante un timeout o error de red, reenvía con la misma clave: obtienes el resultado original.
  • ¿Cambiaste el cuerpo? Usa una clave nueva. La anterior queda ligada a la primera solicitud.
Cuerpo del errorhttp
HTTP/1.1 409 Conflict
X-Request-Id: req_<hex>

{
  "error": {
    "code": "IDEMPOTENCY_KEY_REUSE",
    "message": "..."
  },
  "request_id": "req_<hex>"
}

Endpoints

Todo lo que hace la tienda, por HTTP

Todas las rutas viven bajo /v1 en el host de esta tienda. El dinero siempre es una cadena decimal con moneda ISO 4217, nunca un float. Los esquemas completos de solicitud y respuesta están en el archivo OpenAPI.

Especificación OpenAPI (YAML)

Catálogo

MétodoRutaAlcanceQué hace
GET/v1/catalog/platformscatalog:readPlataformas que tienen servicios publicados actualmente
GET/v1/catalog/servicescatalog:readServicios con el precio en tu moneda y nivel; filtra por plataforma
GET/v1/catalog/services/{id}catalog:readUn servicio con el esquema de sus campos

Pedidos

MétodoRutaAlcanceQué hace
POST/v1/orders/previeworders:writeValida y cotiza sin crear ni cobrar
POST/v1/ordersRequiere Idempotency-Keyorders:writeCrea un pedido: debita la billetera y enruta al mejor proveedor
GET/v1/ordersorders:readLista pedidos, los más recientes primero, con paginación por cursor
POST/v1/orders/batchRequiere Idempotency-Keyorders:writeHasta 100 pedidos en una llamada, cada uno con su propio resultado
GET/v1/orders/{id}orders:readObtiene un pedido por id
POST/v1/orders/{id}/refillorders:writeSolicita un refill dentro de la ventana de garantía
POST/v1/orders/{id}/cancelorders:writeSolicita la cancelación; se reembolsa cuando el proveedor confirma

Billetera

MétodoRutaAlcanceQué hace
GET/v1/wallet/balancewallet:readSaldos por moneda: disponible, dinero, bonificación y reservado

Activos (vendedores)

MétodoRutaAlcanceQué hace
POST/v1/assetsassets:writeCrea un borrador de anuncio; se publica tras la verificación y la moderación
GET/v1/assetsassets:readTus anuncios
PATCH/v1/assets/{id}assets:writeActualiza un anuncio (cuerpo completo; If-Match para bloqueo optimista)
POST/v1/assets/batchassets:writeImporta hasta 1,000 anuncios, emparejados por external_ref
POST/v1/assets/{id}/verifyassets:writeInicia (method) o comprueba (verification_id) una verificación de propiedad
POST/v1/assets/{id}/availabilityassets:writeOculta o muestra un anuncio (no durante una negociación)

Ofertas

MétodoRutaAlcanceQué hace
GET/v1/offersassets:readOfertas recibidas en tus anuncios

Operaciones

MétodoRutaAlcanceQué hace
POST/v1/transactions/{id}/handofftransactions:writeMarca un paso de la guía, agrega un elemento seguro o completa el traspaso
Respuesta (201)http
HTTP/1.1 201 Created
X-Request-Id: req_<hex>
X-Api-Version: 2026-09-23
RateLimit-Limit: <limit>  RateLimit-Remaining: <n>  RateLimit-Reset: <seconds>

{
  "id": "SMP-7K2Q9XHT",
  "status": "routing",
  "service": "<service_id>",
  "link": "https://instagram.com/p/abc",
  "quantity": 1000,
  "charge": "<decimal>",
  "refunded": "0",
  "currency": "USD",
  "start_count": null,
  "remains": null,
  "delivered": null,
  "refill_until": null,
  "created_at": "2026-09-23T12:00:00.000Z",
  "updated_at": "2026-09-23T12:00:00.000Z"
}

Webhooks

Eventos firmados, entregados hasta que los confirmes

Registra un endpoint https en un host público y elige los eventos que quieres. Cada entrega se firma con el secreto del endpoint, que se muestra una sola vez al crearlo.

Encabezados de la entregahttp
POST /webhooks/orders HTTP/1.1
Content-Type: application/json
Webhook-Id: <event id>
Webhook-Timestamp: 1790000000
Webhook-Signature: t=1790000000,v1=<hex HMAC-SHA256(secret, "1790000000.<body>")>

{ "id": "<event id>", "type": "order.partial", "created_at": "2026-09-23T12:05:00.000Z",
  "data": { "orderId": "SMP-7K2Q9XHT", ... } }
Verificación en Node.jsjs
import { createHmac, timingSafeEqual } from 'node:crypto';

export function verifyWebhook(secret, headers, rawBody) {
  const t = headers['webhook-timestamp'];
  const v1 = (headers['webhook-signature'] ?? '')
    .split(',').find((p) => p.startsWith('v1='))?.slice(3) ?? '';
  const expected = createHmac('sha256', secret).update(`${t}.${rawBody}`).digest('hex');
  const fresh = Math.abs(Date.now() / 1000 - Number(t)) < 300; // 5 minutes
  return fresh && expected.length === v1.length
    && timingSafeEqual(Buffer.from(expected), Buffer.from(v1));
}

Verifica una firma

  1. Lee Webhook-Timestamp (t) y el cuerpo crudo de la solicitud tal como llegó.
  2. Calcula el HMAC-SHA256 con el secreto del endpoint sobre la cadena "t.cuerpo".
  3. Compáralo en tiempo constante con el valor v1 de Webhook-Signature.
  4. Rechaza timestamps de más de 5 minutos y deduplica por Webhook-Id.
  5. Responde 2xx rápido y procesa de forma asíncrona.

Reintentos y outbox

Los eventos se escriben en un outbox en la misma transacción de base de datos que el cambio que los originó, así que nada se pierde cuando una entrega falla. Las entregas fallidas se reintentan a 1 min, 5 min, 30 min, 2 h, 6 h, 12 h y 24 h antes de marcarse como muertas.

Eventos a los que puedes suscribirte

  • order.created
  • order.status_changed
  • order.partial
  • order.completed
  • order.refunded
  • order.refill_updated
  • deposit.confirmed
  • offer.created
  • offer.updated
  • reservation.created
  • transaction.updated
  • payout.updated
  • listing.updated
  • dispute.updated

Reglas del endpoint

  • Solo https://, en un host público; las direcciones privadas e internas se rechazan.
  • Suscríbete a eventos específicos o a todos.
  • El secreto de firma se muestra una sola vez, al crearlo.

Compatibilidad

Agrega esta tienda a cualquier panel SMM

POST /api/v2 implementa el contrato común “SMM API v2”: envía key y action como campos de formulario o JSON. Las mismas claves, alcances y límites que /v1; solo cambia el formato, y los errores vuelven como { "error": "mensaje" }.

Acciones compatibles

  • services: el catálogo con rate, min, max e indicadores de refill/cancel
  • add: crea un pedido (service, link, quantity, comments, usernames, runs, interval)
  • status: un pedido, o hasta 100 con orders=id1,id2
  • balance: saldo disponible en la moneda de tu cuenta
  • refill: solicita refills para uno o más pedidos
  • refill_status: estado de uno o más refills
  • cancel: solicita la cancelación de uno o más pedidos

Los paneles no envían clave de idempotencia, así que se deriva del contenido del pedido y del minuto actual; la ventana de pedidos duplicados cubre el resto.

Solicitudbash
curl -X POST https://YOUR-DOMAIN/api/v2 \
  -d key=smp_live_xxxxxxxxxx_... \
  -d action=add \
  -d service=<service_id> \
  -d link=https://instagram.com/p/abc \
  -d quantity=1000

{ "order": "SMP-7K2Q9XHT" }

Errores

Un solo formato para cada error

Toda respuesta fuera de 2xx tiene el mismo cuerpo. Integra por el código, no por el mensaje: los mensajes pueden cambiar, los códigos no. El request_id también viaja en el encabezado X-Request-Id.

Cuerpo del errorhttp
HTTP/1.1 400 Bad Request
X-Request-Id: req_<hex>

{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Invalid request.",
    "details": {
      "fields": [{ "path": "quantity", "message": "..." }]
    }
  },
  "request_id": "req_<hex>"
}
CódigoHTTPSignificado
VALIDATION_ERROR400Cuerpo o encabezados inválidos; details.fields lista cada ruta y problema
UNAUTHORIZED401Clave ausente, inválida, revocada o vencida
INSUFFICIENT_FUNDS402Saldo de la billetera insuficiente para la cotización
FORBIDDEN403Clave sin el alcance, IP no permitida, subusuario sin permiso o cuenta suspendida
NOT_FOUND404El pedido, servicio o anuncio no existe para esta cuenta
CONFLICT409Conflicto de estado, como el límite de claves activas
INVALID_TRANSITION409El pedido o la operación no puede pasar a ese estado
DUPLICATE_ORDER409Mismo servicio, enlace y cantidad dentro de la ventana de duplicados
IDEMPOTENCY_KEY_REUSE409Idempotency-Key ya usada con otro cuerpo
ALREADY_RESERVED409El activo está reservado por otro comprador
POLICY_BLOCKED422Servicio o país bloqueado por la política de la plataforma
MARGIN_GUARD422Ningún proveedor puede atender este pedido al precio publicado
UNPROCESSABLE422La solicitud es válida pero no puede cumplirse
RATE_LIMITED429Límite por clave alcanzado; espera los segundos de Retry-After
INTERNAL500Error inesperado; contacta a soporte con el request_id
PROVIDER_ERROR502Falla del proveedor; el pedido se reintenta o se reembolsa
NO_ROUTE503No hay ruta de proveedor disponible ahora; reintenta más tarde
NOT_CONFIGURED503Función no configurada en esta tienda

Quién puede usarla

Disponible en el plan Revendedor

Las claves de API y los endpoints de webhook los crea el titular de la cuenta en el plan Revendedor. Los pedidos hechos con una clave se debitan de la billetera de la cuenta y aparecen en el mismo panel que los pedidos manuales. Los subusuarios no pueden crear claves.

Cómo construir una integración de reventa sobre la API de SocialMediaPRO

Ya sea un panel que necesita un proveedor confiable, una herramienta de agencia que hace pedidos para clientes o un inventario de vendedor que debe mantenerse sincronizado con el marketplace, la integración sigue el mismo patrón: una clave con alcance, escrituras idempotentes y eventos que verificas antes de confiar en ellos.

Un contrato, versionado por fecha

Todos los endpoints viven bajo /v1 en el host de la tienda con la que integras. Las respuestas son JSON, el dinero es una cadena decimal acompañada de una moneda ISO 4217 y las fechas siguen ISO 8601. Cada respuesta trae el encabezado X-Api-Version con la fecha del contrato en uso y un X-Request-Id que puedes citar ante soporte. Los errores siempre tienen el mismo cuerpo: un objeto error con un código estable, un mensaje legible y detalles opcionales, más el request_id.

El archivo OpenAPI 3.1 describe cada ruta, esquema y código de error. Impórtalo en tu cliente HTTP o generador de código y tendrás solicitudes tipadas para catálogo, pedidos, billetera, anuncios, ofertas y traspasos de operaciones.

Claves, alcances y la cuenta por la que actúan

La clave la crea el titular de la cuenta en el plan Revendedor y se muestra una sola vez; solo se guarda su hash. Al crearla eliges sus alcances, una lista opcional de hasta 20 IP permitidas y un vencimiento opcional. La rotación crea una clave nueva con los mismos alcances y revoca la anterior, así que puedes cambiar credenciales sin detener la operación. Los pedidos hechos con una clave se debitan de la billetera de la cuenta y aparecen en el mismo panel que los pedidos manuales, con el origen marcado como API.

Cada clave hereda el límite de solicitudes por minuto del nivel de cliente de la cuenta. Los encabezados RateLimit-Limit, RateLimit-Remaining y RateLimit-Reset te dicen dónde estás; al superar el límite la API responde 429 con Retry-After, y lo correcto es esperar exactamente ese tiempo.

Escrituras idempotentes y lotes

Crear un pedido es la única llamada que mueve dinero, por eso está protegida dos veces. Primero, el encabezado Idempotency-Key es obligatorio: repetir una solicitud con la misma clave devuelve el pedido original sin un segundo cargo, y reutilizar la clave con otro cuerpo se rechaza con 409 IDEMPOTENCY_KEY_REUSE. Segundo, una ventana de duplicados detecta el mismo servicio, enlace y cantidad enviados otra vez en un intervalo corto sin coincidencia de clave, y devuelve 409 DUPLICATE_ORDER.

Los lotes aceptan hasta 100 pedidos por llamada. Cada elemento se valida y se cobra por separado, identificado por la clave del lote más su índice, y la respuesta trae un resultado por elemento, así que una línea defectuosa nunca bloquea al resto. Usa POST /v1/orders/preview primero cuando quieras el cargo exacto y el resultado de la validación sin crear nada.

  • Genera un UUID por pedido lógico y guárdalo antes de enviar.
  • Ante un timeout, reenvía con la misma clave; nunca generes otra para el mismo pedido.
  • Trata los códigos 4xx como definitivos y los 5xx y 429 como reintentables con backoff.

Webhooks en los que puedes confiar

Cada cambio de estado se escribe en un outbox en la misma transacción de base de datos que el propio cambio, y un despachador lo entrega a tu endpoint https con tres encabezados: Webhook-Id, Webhook-Timestamp y Webhook-Signature. La firma es un HMAC-SHA256 del timestamp, un punto y el cuerpo crudo, calculado con el secreto del endpoint que se muestra una vez al crearlo. Verifícala en tiempo constante, rechaza timestamps de más de cinco minutos y deduplica por Webhook-Id, porque un evento reintentado lleva el mismo id.

Las entregas que no reciben 2xx se reintentan a 1 minuto, 5 minutos, 30 minutos, 2 horas, 6 horas, 12 horas y 24 horas antes de marcarse como muertas. Responde rápido y procesa de forma asíncrona; un handler lento es la causa más común de procesamiento duplicado.

Paneles hijos a través del endpoint SMM v2

Si tu panel ya habla el formato “SMM API v2”, muy extendido en el mercado, puedes agregar esta tienda como proveedor pegando la URL /api/v2 y tu clave. Se admiten las acciones services, add, status, balance, refill, refill_status y cancel, los precios vuelven en la moneda y el nivel de tu cuenta, y los errores usan el formato plano { "error": "mensaje" } que esos paneles esperan. La idempotencia se deriva del contenido del pedido y del minuto actual, así que los envíos duplicados por accidente dentro del mismo minuto se unifican.

Preguntas frecuentes

¿Qué plan necesito para usar la API?

El plan Revendedor. Las claves de API y los endpoints de webhook los crea el titular de la cuenta; los subusuarios no pueden crearlos. Las claves son credenciales de servidor y nunca deben incrustarse en un navegador ni en una app móvil.

¿Cómo autentico una solicitud?

Envía la clave como Authorization: Bearer smp_live_… o en el encabezado X-Api-Key. La clave debe tener el alcance que exige el endpoint, por ejemplo orders:write para crear un pedido o catalog:read para listar servicios.

¿Qué pasa si mi solicitud da timeout después de crear un pedido?

Reenvíala con el mismo Idempotency-Key. Recibes el pedido original y no se cobra nada dos veces. Si envías otro cuerpo con la misma clave, la API responde 409 IDEMPOTENCY_KEY_REUSE.

¿Cómo verifico un webhook?

Calcula el HMAC-SHA256 con el secreto del endpoint sobre la cadena formada por Webhook-Timestamp, un punto y el cuerpo crudo, y compáralo en tiempo constante con el valor v1 de Webhook-Signature. Rechaza timestamps de más de 5 minutos y deduplica por Webhook-Id.

¿Cuál es el límite de solicitudes?

Cada clave hereda el límite de solicitudes por minuto de tu nivel de cliente, que se muestra en esta página. Los encabezados RateLimit-* informan la ventana actual y la respuesta 429 incluye Retry-After en segundos.

¿Los precios en la API son los mismos que en el sitio?

Sí. GET /v1/catalog/services devuelve el precio ya convertido a la moneda de tu cuenta con el descuento de tu nivel, y POST /v1/orders/preview devuelve el cargo exacto, incluidos descuentos por volumen y cupones, antes de confirmar.

¿Puedo usar la API para anuncios del marketplace?

Sí. Con el alcance assets:write puedes crear y actualizar anuncios, importar hasta 1,000 de una vez, iniciar la verificación de propiedad y cambiar la disponibilidad; assets:read lista tus anuncios y ofertas, y transactions:write registra pasos del traspaso en una operación.

¿Listo para integrar?

En el plan Revendedor, crea una clave, descarga el archivo OpenAPI y envía tu primer pedido desde tu propio sistema.

Nunca vendemos reseñas ni calificaciones. Algunas plataformas restringen los servicios de interacción o la transferencia de cuentas en sus términos; tú eres responsable de las reglas de cada plataforma que usas.