EPICODES · MAYORISTA

API de Catálogo

Con una sola request obtenés todo el catálogo mayorista en tiempo real: precios en ARS y USDT, stock, tiempos de entrega, ofertas con su fecha de vencimiento y las portadas de cada juego.

public_catalog_v1 · REST · JSON → ¿Buscabas la API de pedidos (tu historial de compras)?

1Endpoint y autenticación

DatoValor
URLhttps://mayoristas.epicodes.com.ar/api.php
MétodoPOST
Content-Typeapplication/json
API KeyTe la pasamos por privado. Va en el body de cada request.
⚠️ Usá el subdominio. La URL correcta es mayoristas.epicodes.com.ar. La vieja epicodes.com.ar/mayoristas/... ya no funciona.

2Cómo hacer la request

En el body (JSON) mandás solo dos campos:

{
  "action": "public_catalog_v1",
  "api_key": "TU_API_KEY"
}

Una request devuelve el catálogo entero (todas las combinaciones título × plataforma × licencia). No hace falta paginar ni hacer varias llamadas.

Ejemplo con curl

curl -X POST "https://mayoristas.epicodes.com.ar/api.php" \
  -H "Content-Type: application/json" \
  -d '{"action":"public_catalog_v1","api_key":"TU_API_KEY"}'

3Estructura de la respuesta

CampoDescripción
oktrue si salió bien.
catalog_versionNúmero de versión del catálogo (para caché, ver punto 6).
catalog_version_isoFecha/hora de esa versión.
tsTimestamp de la respuesta.
rate_limitTu estado de límites (ver punto 7).
itemsArray con todos los productos.

4Campos de cada producto

Identificación

CampoTipoDescripción
provider_product_idstringIdentificador del juego. Ej: "ea-sports-fc-26". Las 4 variantes de un mismo juego comparten este valor.
provider_variant_idstringIdentificador de la variante exacta (juego + plataforma + licencia). Ej: "ea-sports-fc-26-ps5-primario". Único en todo el catálogo: usá este como clave primaria de tu sync.
skustringMismo valor que provider_variant_id, por si tu sistema espera ese nombre. No es un campo distinto.
titlestringNombre del juego.
platformstring"PS4" o "PS5".
licensestring"Primario" o "Secundario".
Sobre la estabilidad de los IDs. Los generamos nosotros a partir del catálogo normalizado, así que no dependés de parsear ni normalizar title de tu lado. Son inmunes a cambios cosméticos del nombre comercial: tildes, mayúsculas, puntuación, apóstrofes o espacios de más no mueven el ID.

Lo que sí lo movería es que cambiemos el nombre de un juego en serio (no su tipografía). Si eso pasa, congelamos el ID viejo de nuestro lado para que tu integración no se rompa, y te avisamos. Preferimos decirlo explícito: no es un UUID inmutable, es un identificador estable que nosotros sostenemos.

provider_product_id es además el mismo slug que ya ves dentro de cover_url, así que podés cruzarlos.

Precio

CampoTipoDescripción
price_arsnumber · nullPrecio en pesos, a valor mayorista. Si hay oferta, ya viene aplicada.
price_usdtnumber · nullPrecio en USDT.

Pueden venir null si esa variante no tiene precio cargado.

Stock y entrega

CampoTipoDescripción
available_countnumberUnidades para entrega inmediata.
stock_statusstring"instant" (hay stock: se entrega en el momento) o "up_to_6h" (sin stock: se puede pedir igual y queda pendiente hasta que conseguimos la cuenta). El valor conserva ese nombre por compatibilidad: el tiempo aproximado depende de la hora del pedido (ver los tiempos por franja).
delivery_modestringTexto legible: "instantáneo" o "hasta 6h". El segundo también quedó fijo por compatibilidad: no lo muestres como plazo de entrega.

Ofertas ✨ (nuevo)

CampoTipoDescripción
on_salebooleantrue si el producto está en oferta.
offer_sourcestring · nullOrigen de la oferta: "sony", "epicodes" o null.
offer_ends_atstring ISO · nullFecha y hora de fin de la oferta, en ISO 8601 con zona horaria. Ej: "2026-07-15T22:00:00-03:00". Es null cuando la oferta no tiene fecha de vencimiento.

Imágenes

CampoTipoDescripción
cover_urlstring · nullPortada del juego (webp).
cover_thumb_urlstring · nullMiniatura (webp).

5Cómo interpretar las ofertas

📌 Son precios mayoristas. price_ars / price_usdt son el valor a precio mayorista (el que pagás vos). Si el producto está en oferta, ya viene con la oferta aplicada — no tenés que calcular ningún porcentaje. El precio de venta al público lo definís vos.

6Detección de cambios (recomendado)

Cada respuesta trae catalog_version. Guardá el último valor que procesaste: si en la próxima llamada viene el mismo número, el catálogo no cambió y podés saltear el reprocesamiento. Cambia apenas se modifica un precio, stock u oferta.

7Límite de uso (rate limit)

En cada respuesta, el objeto rate_limit te informa:

CampoDescripción
limit_per_minuteTu límite (60).
user_remainingRequests que te quedan este minuto.
global_remainingCupo global compartido restante.
reset_msMilisegundos hasta que se reinicia el contador.

8Manejo de errores

Si algo falla, ok viene en false con un error y un code:

CodeerrorSignificado
401missing_api_keyNo mandaste la key.
403invalid_api_keyKey inválida o revocada.
429rate_limitedPasaste el límite. Incluye retry_after_ms con cuánto esperar.
Ante un 429: esperá los retry_after_ms y reintentá. No reintentes en loop sin esperar.

9Qué podés armar con esto

10Ejemplo de respuesta 200 OK

La estructura es la real; los precios y el stock del ejemplo son ilustrativos.

{
  "ok": true,
  "api": "public_catalog_v1",
  "catalog_version": 1783382337162,
  "catalog_version_iso": "2026-07-06T23:58:57.271Z",
  "ts": "2026-07-07T00:03:29.365Z",
  "rate_limit": {
    "limit_per_minute": 60,
    "user_remaining": 59,
    "global_remaining": 299,
    "reset_ms": 31349
  },
  "items": [
    {
      "provider_product_id": "ea-sports-fc-26",
      "provider_variant_id": "ea-sports-fc-26-ps4-primario",
      "sku": "ea-sports-fc-26-ps4-primario",
      "title": "EA SPORTS FC 26",
      "platform": "PS4",
      "license": "Primario",
      "price_ars": 10000,
      "price_usdt": 7,
      "delivery_mode": "instantáneo",
      "stock_status": "instant",
      "available_count": 12,
      "on_sale": true,
      "offer_source": "sony",
      "offer_ends_at": "2026-07-15T22:00:00-03:00",
      "cover_url": "https://epicodes.com.ar/cdn/covers/ea-sports-fc-26-ps4-md.webp",
      "cover_thumb_url": "https://epicodes.com.ar/cdn/covers/ea-sports-fc-26-ps4-thumb.webp"
    },
    {
      "provider_product_id": "mortal-kombat-11",
      "provider_variant_id": "mortal-kombat-11-ps4-primario",
      "sku": "mortal-kombat-11-ps4-primario",
      "title": "Mortal Kombat 11",
      "platform": "PS4",
      "license": "Primario",
      "price_ars": 20000,
      "price_usdt": 14,
      "delivery_mode": "hasta 6h",
      "stock_status": "up_to_6h",
      "available_count": 0,
      "on_sale": false,
      "offer_source": null,
      "offer_ends_at": null,
      "cover_url": "https://epicodes.com.ar/cdn/covers/mortal-kombat-11-ps4-md.webp",
      "cover_thumb_url": "https://epicodes.com.ar/cdn/covers/mortal-kombat-11-ps4-thumb.webp"
    }
  ]
}