Saltar al contenido principal

API pública v1

API REST para integrar un TPV, una tienda online o un CRM con tu programa de fidelización. Todas las rutas cuelgan de /api/v1 y devuelven JSON.

Antes de empezar

Necesitas una clave API de tu cuenta con los ámbitos adecuados. Cada llamada lleva Authorization: Bearer mk_.... Las claves de la cuenta anfitriona no sirven (403).

Para crear y administrar programas, niveles, campañas, recompensas y cupones, consulta la API de gestión. Si prefieres tokens de corta duración, mira OAuth2.

En los ejemplos, $BASE es la dirección de tu plataforma y $KEY tu clave.

Resumen​

Método y rutaÁmbitoQué hace
GET /api/v1/members/lookupreadBusca un socio por teléfono, correo o tarjeta
GET /api/v1/members/{memberId}/balancereadSaldo y nivel
GET /api/v1/members/{memberId}/transactionsreadHistorial de movimientos
POST /api/v1/transactions/purchasetransactions:writeRegistra una compra y suma puntos
POST /api/v1/transactions/actiontransactions:writeSuma puntos por una acción
POST /api/v1/transactions/redeemtransactions:writeDescuenta puntos
POST /api/v1/transactions/adjusttransactions:writeAjuste manual (solo suma)
GET /api/v1/coupons/validatereadComprueba si un cupón se puede usar
POST /api/v1/coupons/redeemcoupons:writeCanjea un cupón en caja

Todas las rutas con programId exigen que el programa y el socio pertenezcan a la cuenta de la clave.

Referencia interactiva​

La plataforma sirve la referencia OpenAPI (public-v1) en /docs/api-v1, con un visor de código abierto (Swagger UI) y el botón Try it out. Pulsa Authorize, pega una clave de pruebas y ejecuta las llamadas.

Solo claves de pruebas

«Probar» solo envía llamadas con claves mk_test_..., que únicamente autentican mientras la cuenta está en modo pruebas. Con una clave real (mk_...) la página no envía la clave ni la llamada. Cada respuesta lleva X-IncentIA-Test-Mode: true.

Socios​

Buscar un socio​

curl -s "$BASE/api/v1/members/lookup?programId=1&phone=%2B34600111222" \
-H "Authorization: Bearer $KEY"
ParámetroObligatorioNotas
programIdSíId del programa de fidelización
phone, email, cardNumberUno de los tresSi envías varios, se usa en este orden: teléfono, correo, tarjeta

Respuesta 200:

{
"memberId": 42, "firstName": "Ana", "lastName": "Ruiz",
"email": "ana@example.com", "phone": "+34600111222", "status": "Active",
"balance": { "current": 320, "totalEarned": 900, "totalRedeemed": 580,
"tierName": "Plata", "tierLevel": 2 }
}

Devuelve 400 si no envías ningún identificador y 404 si no existe.

Saldo​

GET /api/v1/members/{memberId}/balance?programId=1 devuelve memberId, programId, currentBalance, totalEarned, totalRedeemed, totalExpired, tierName y tierLevel.

Historial​

GET /api/v1/members/{memberId}/transactions?programId=1&limit=20

limit va de 1 a 200 (por defecto 20). Los movimientos salen del más reciente al más antiguo. Para paginar, pasa cursor con el nextCursor de la respuesta anterior; nextCursor es null en la última página. offset sigue funcionando solo si no envías cursor, pero es heredado.

{ "total": 57, "nextCursor": "…", "items": [
{ "id": 9001, "type": "Earn", "points": 50, "description": "Compra",
"externalReference": "ORDER-12345", "createdAt": "2026-10-20T10:15:00Z" } ] }

Movimientos de puntos​

Los cuatro endpoints aceptan externalReference, un identificador tuyo y único por operación, no por ticket: si un mismo ticket genera una compra y un canje, usa referencias distintas (por ejemplo T-1001-earn y T-1001-redeem). Si reenvías la misma referencia en el mismo endpoint, no se duplica el movimiento: es la forma segura de reintentar tras un fallo de red. Si la reutilizas para otro tipo de movimiento, la API responde 409 con ExternalReference already used for a different operation. y no mueve puntos.

Compra​

curl -s -X POST "$BASE/api/v1/transactions/purchase" \
-H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \
-d '{"memberId":42,"programId":1,"amount":49.99,"externalReference":"ORDER-12345"}'
CampoObligatorioNotas
memberId, programIdSí
amountSíMayor que 0. Una devolución con importe 0 o negativo da 400
externalReferenceNoClave de idempotencia

Respuesta 200: pointsEarned, currentBalance, tierName y transactions (lista con id, type, points, description). Las campañas activas pueden añadir movimientos de bonificación.

Acción​

POST /api/v1/transactions/action con memberId, programId, actionType y, opcionalmente, customEventCode y externalReference.

actionType acepta: Registration (1), Birthday (2), Review (3), CheckIn (4), SocialShare (5), Referral (6), ProfileComplete (7) y Custom (99). Respuesta: pointsEarned, currentBalance y transactionId. Si ninguna regla premia la acción, devuelve pointsEarned: 0 y transactionId: null.

Canje de puntos​

POST /api/v1/transactions/redeem con memberId, programId, points y, opcionalmente, description y externalReference. Respuesta: pointsRedeemed, currentBalance y transactionId. Sin saldo suficiente devuelve 400 (Insufficient points.).

Ajuste manual​

POST /api/v1/transactions/adjust con memberId, programId, points (entero mayor que 0), description y externalReference. Es una corrección manual: no aplica multiplicadores de campaña. Respuesta: pointsAdjusted, currentBalance y transactionId.

Cupones​

Validar​

curl -s "$BASE/api/v1/coupons/validate?code=SUMMER20&memberId=42" \
-H "Authorization: Bearer $KEY"

code es obligatorio; memberId es opcional, pero sin él un cupón personal o con nivel o coste en puntos se considera no válido. La respuesta incluye valid y los motivos: isExpired, isMaxUsed, alreadyUsedByMember, ownerMismatch, tierTooLow, insufficientPoints, además de couponType, discountValue, pointsCost, minTierLevel, validFrom y validUntil. Un código desconocido da 404 con valid: false.

Canjear​

curl -s -X POST "$BASE/api/v1/coupons/redeem" \
-H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \
-d '{"code":"SUMMER20","memberId":42,"externalReference":"TICKET-778"}'

Respuesta 200: success, couponType, discountValue, pointsSpent y usageId. Con la misma externalReference para el mismo socio, un reintento devuelve la respuesta original sin gastar otro uso. Si esa referencia ya canjeó el cupón para otro socio, recibes 409.

Idempotencia​

Cualquier POST, PATCH o DELETE de /api/v1 acepta la cabecera opcional Idempotency-Key (1-128 caracteres imprimibles; usa un UUID por operación). Así puedes reintentar sin duplicar nada:

  • Mismo valor y misma petición (método, ruta, query y cuerpo; en multipart/form-data se comparan los campos y ficheros, no el boundary, así que puedes reconstruir la petición al reintentar) en las 24 h siguientes: recibes la respuesta original, con la cabecera Idempotent-Replayed: true. La operación no se repite.
  • Mismo valor con otra petición: 409 con code: idempotency_key_reused.
  • Mismo valor mientras la primera petición sigue en curso: 409 con code: idempotency_request_in_progress y Retry-After: 1.

Las respuestas 5xx, 401, 403, 408, 409, 425 y 429 no se guardan: puedes reintentar con el mismo valor. Cada clave de API tiene su propio espacio de valores. La cabecera es obligatoria en POST /api/v1/claims, POST /api/v1/participations, POST /api/v1/participations/{id}/play, POST /api/v1/coupons/batches, POST /api/v1/members/imports y POST /api/v1/jobs/import y jobs/export.

Códigos de error​

CódigoCuándo
400Datos no válidos, cupón inactivo, caducado o agotado, sin puntos, nivel insuficiente
401Falta la clave o no es válida
403La clave no tiene el ámbito, es de la cuenta anfitriona o el socio no es de tu cuenta
404Socio, programa o cupón inexistente (también socios borrados)
409externalReference ya usada con otro socio, o Idempotency-Key reutilizada o en curso (ver Idempotencia)
429Superaste el límite de ráfaga, minuto u hora de la clave, o la cuota mensual. Retry-After indica los segundos hasta el reinicio de esa ventana

El cuerpo es application/problem+json con un code estable (bad_request, not_found, conflict, rate_limited, idempotency_key_reused, invalid_idempotency_key, business_rule_violated, ...); el texto legado sigue disponible en error.

Relacionado​