LoyalEats

Developers

Documentación

Referencia API

Quickstart

API externa v1

Overview
Quickstart
Endpoints
POST /auth/tokenGET /customersGET /customers/:idGET /transactions
OverviewQuickstartAutenticaciónEndpointsErroresNotas

Documentación

Quickstart

API de LoyalEats

Documentación técnica para consultar clientes y transacciones por tienda con autenticación basada en apiKey, secretKey, bearer tokens temporales y límites operativos por apiKey.

Ver autenticaciónVer endpoints

Overview

Qué resuelve esta API

La API externa de LoyalEats permite a cada tienda consultar los clientes y transacciones de sus propias campañas sin exponer operaciones internas del dashboard.

Ownership por tienda

Todos los recursos se filtran por la tienda dueña de la credencial. Si envías un campaignId, debe pertenecer a ese shop.

Auth segura

El flujo es apiKey + secretKey para obtener un token temporal y luego consumir los endpoints con bearer token. Cada apiKey tiene límites operativos para proteger la base de datos.

Read-only

Esta primera versión está orientada a lectura: clientes, detalle de cliente y transacciones, con DTOs públicos estables desacoplados del modelo interno y un uso controlado para partners.

Quickstart

Integra en minutos

Si ya tienes tus credenciales, estos son los pasos mínimos para empezar.

Paso 1

Obtén tu API_KEY y SECRET_KEY desde Configuración > Mi cuenta.

Paso 2

Solicita un access token de 15 minutos en POST /api/external/v1/auth/token.

Paso 3

Consume los endpoints con Authorization: Bearer <token>.

curl

Ejemplo

curl -X POST "https://tu-dominio.com/api/external/v1/auth/token" \
  -H "Content-Type: application/json" \
  -d '{
    "apiKey": "le_pk_xxxxxxxxxxxx",
    "secretKey": "le_sk_xxxxxxxxxxxxxxxxxxxxxxxx"
  }'

curl "https://tu-dominio.com/api/external/v1/customers?page=1&pageSize=20" \
  -H "Authorization: Bearer TU_ACCESS_TOKEN"

fetch

Ejemplo

const tokenResponse = await fetch("https://tu-dominio.com/api/external/v1/auth/token", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({
    apiKey: "le_pk_xxxxxxxxxxxx",
    secretKey: "le_sk_xxxxxxxxxxxxxxxxxxxxxxxx",
  }),
});

const { accessToken } = await tokenResponse.json();

const customersResponse = await fetch(
  "https://tu-dominio.com/api/external/v1/customers?page=1&pageSize=20",
  {
    headers: {
      Authorization: `Bearer ${accessToken}`,
    },
  },
);

const customers = await customersResponse.json();

Autenticación

Modelo de acceso

Primero obtén un access token con tus credenciales. Luego usa ese token como Bearer en todos los endpoints de datos.

Endpoint de token

POST /api/external/v1/auth/token

Envía apiKey y secretKey en el body JSON. Si una apiKey excede el límite permitido, recibirás 429.

Respuesta esperada

La respuesta devuelve accessToken y expiresIn: 900. Ese token debe enviarse en Authorization: Bearer. Los endpoints de lectura aplican rate limit por apiKey.

Endpoints

Referencia técnica

A continuación encontrarás los cuatro endpoints disponibles en la API externa v1 y ejemplos reales del contrato público expuesto.

POST/api/external/v1/auth/token

Generar access token

Valida la pareja API_KEY + SECRET_KEY y devuelve un bearer token temporal para consumir la API externa.

No requiere bearer token. Usa apiKey y secretKey en el body.

Body

apiKey

Requerido

Identificador público de la credencial asignada a la tienda.

secretKey

Requerido

Secreto asociado a la credencial. Solo se muestra al crear o regenerar.

curl

Ejemplo

curl -X POST "https://tu-dominio.com/api/external/v1/auth/token" \
  -H "Content-Type: application/json" \
  -d '{
    "apiKey": "le_pk_xxxxxxxxxxxx",
    "secretKey": "le_sk_xxxxxxxxxxxxxxxxxxxxxxxx"
  }'

fetch

Ejemplo

const response = await fetch("https://tu-dominio.com/api/external/v1/auth/token", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    apiKey: "le_pk_xxxxxxxxxxxx",
    secretKey: "le_sk_xxxxxxxxxxxxxxxxxxxxxxxx",
  }),
});

const data = await response.json();

json

Ejemplo

{
  "success": true,
  "accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "expiresIn": 900
}
GET/api/external/v1/customers

Listar clientes

Devuelve clientes de una campaña específica o de todas las campañas de la tienda autenticada.

Requiere Authorization: Bearer <token>.

Parámetros

campaignId

Opcional

Si se envía, la campaña debe pertenecer a la tienda. Si no se envía, la consulta agrega todas las campañas del shop.

page

Opcional

Número de página. Valor por defecto: 1.

pageSize

Opcional

Tamaño de página. Máximo actual: 100.

statusFilter

Opcional

Acepta "all", "active" o "inactive".

curl

Ejemplo

curl "https://tu-dominio.com/api/external/v1/customers?campaignId=6844a2d1b0c123456789abcd&page=1&pageSize=20&statusFilter=active" \
  -H "Authorization: Bearer TU_ACCESS_TOKEN"

fetch

Ejemplo

const response = await fetch(
  "https://tu-dominio.com/api/external/v1/customers?campaignId=6844a2d1b0c123456789abcd&page=1&pageSize=20&statusFilter=active",
  {
    headers: {
      Authorization: "Bearer TU_ACCESS_TOKEN",
    },
  },
);

const data = await response.json();

json

Ejemplo

{
  "success": true,
  "items": [
    {
      "id": "6844a6f9b0c123456789abef",
      "shopId": "shop-123",
      "campaignId": "6844a2d1b0c123456789abcd",
      "firstName": "Ana",
      "lastName": "Pérez",
      "secondLastName": "Díaz",
      "email": "ana@correo.com",
      "phone": "51999999999",
      "points": 12,
      "rewards": 1,
      "rewardsGranted": 0,
      "maxPoints": 20,
      "isActive": true,
      "createdAt": "2026-06-03T14:05:00.000Z",
      "dateOfBirth": "1995-08-21T00:00:00.000Z",
      "customFields": {
        "favoriteDrink": "Cold Brew"
      }
    }
  ],
  "pagination": {
    "page": 1,
    "pageSize": 20,
    "total": 1,
    "totalPages": 1
  }
}
GET/api/external/v1/customers/:id

Obtener un cliente

Devuelve el detalle de un cliente específico siempre que su campaña pertenezca a la tienda autenticada.

Requiere Authorization: Bearer <token>.

Parámetros

id

Requerido

ObjectId del cliente en la colección cards_users.

curl

Ejemplo

curl "https://tu-dominio.com/api/external/v1/customers/6844a6f9b0c123456789abef" \
  -H "Authorization: Bearer TU_ACCESS_TOKEN"

fetch

Ejemplo

const response = await fetch(
  "https://tu-dominio.com/api/external/v1/customers/6844a6f9b0c123456789abef",
  {
    headers: {
      Authorization: "Bearer TU_ACCESS_TOKEN",
    },
  },
);

const data = await response.json();

json

Ejemplo

{
  "success": true,
  "item": {
    "id": "6844a6f9b0c123456789abef",
    "shopId": "shop-123",
    "campaignId": "6844a2d1b0c123456789abcd",
    "firstName": "Ana",
    "lastName": "Pérez",
    "secondLastName": "Díaz",
    "email": "ana@correo.com",
    "phone": "51999999999",
    "points": 12,
    "rewards": 1,
    "rewardsGranted": 0,
    "maxPoints": 20,
    "isActive": true,
    "createdAt": "2026-06-03T14:05:00.000Z",
    "dateOfBirth": "1995-08-21T00:00:00.000Z",
    "customFields": {
      "favoriteDrink": "Cold Brew"
    }
  }
}
GET/api/external/v1/transactions

Listar transacciones

Devuelve transacciones de una campaña específica o agregadas de todas las campañas de la tienda.

Requiere Authorization: Bearer <token>.

Parámetros

campaignId

Opcional

Si se envía, debe pertenecer a la tienda autenticada. Si no se envía, devuelve transacciones de todas las campañas del shop.

clientId

Opcional

Filtra por el identificador público del cliente.

page

Opcional

Número de página. Valor por defecto: 1.

pageSize

Opcional

Tamaño de página. Máximo actual: 100.

dateFrom

Opcional

Fecha/hora inicial en formato ISO 8601.

dateTo

Opcional

Fecha/hora final en formato ISO 8601.

curl

Ejemplo

curl "https://tu-dominio.com/api/external/v1/transactions?campaignId=6844a2d1b0c123456789abcd&page=1&pageSize=20&dateFrom=2026-06-01T00:00:00.000Z" \
  -H "Authorization: Bearer TU_ACCESS_TOKEN"

fetch

Ejemplo

const response = await fetch(
  "https://tu-dominio.com/api/external/v1/transactions?campaignId=6844a2d1b0c123456789abcd&page=1&pageSize=20&dateFrom=2026-06-01T00:00:00.000Z",
  {
    headers: {
      Authorization: "Bearer TU_ACCESS_TOKEN",
    },
  },
);

const data = await response.json();

json

Ejemplo

{
  "success": true,
  "items": [
    {
      "id": "6844b013b0c123456789ac10",
      "campaignId": "6844a2d1b0c123456789abcd",
      "customerId": "6844a6f9b0c123456789abef",
      "branchId": "6844af77b0c123456789ac01",
      "employeeId": "6844af8bb0c123456789ac02",
      "productId": "6844afc2b0c123456789ac03",
      "action": "add_points",
      "email": "ana@correo.com",
      "stampCount": 1,
      "rewardCount": 0,
      "createdAt": "2026-06-03T14:22:00.000Z",
      "productName": "Latte grande",
      "branchName": "Miraflores",
      "employeeName": "Luis Torres"
    }
  ],
  "pagination": {
    "page": 1,
    "pageSize": 20,
    "total": 1,
    "totalPages": 1
  }
}

Errores

Códigos más comunes

Estos son los estados HTTP que deberías contemplar al integrar la API.

401

No autenticado

Ocurre cuando falta el bearer token, el token es inválido o las credenciales del token endpoint no son correctas.

403

Sin acceso al recurso

Se devuelve cuando el campaignId o el cliente no pertenecen a la tienda autenticada.

404

Recurso no encontrado

Se usa cuando el cliente solicitado no existe o no tiene una campaña válida asociada.

422

Parámetros inválidos

Se devuelve cuando falta apiKey o secretKey, cuando se envía searchTerm o cuando algún parámetro como page, pageSize, statusFilter, dateFrom, dateTo o IDs no tiene formato válido.

429

Demasiadas solicitudes

Se devuelve cuando una apiKey excede el límite de requests permitido en la ventana actual.

500

Error interno

Se devuelve ante una falla inesperada del servidor o del acceso a base de datos.

Notas

Ownership y paginación

Dos conceptos importantes para interpretar correctamente los resultados.

Cómo funciona campaignId

Si envías campaignId, la API valida que esa campaña pertenezca a la tienda autenticada.

Si no envías campaignId, la consulta agrega los resultados de todas las campañas asociadas al shop dueño del token.

Paginación actual

Los listados devuelven siempre un objeto pagination con:

page: página solicitada.

pageSize: cantidad de resultados por página.

total: cantidad total de registros.

totalPages: total de páginas disponibles.

page y pageSize se validan de forma estricta. El máximo actual de pageSize es 100.