API de partners de BuyCheapKeys

API REST/JSON para importar nuestro catálogo y venderlo en tu propia web. Los pedidos se pagan con tu saldo prepago y se entregan automáticamente desde el proveedor más barato disponible.

URL base: https://buycheapkeys.com/partner-api/v1 Obtener claves API Descargar la especificación OpenAPI 3.1

Visión general

URL base: https://buycheapkeys.com/partner-api/v1. Peticiones y respuestas en JSON (UTF-8). Los precios están en EUR con dos decimales y no incluyen IVA. Las fechas son ISO 8601 en UTC.

  • Catálogo: lista y sincroniza de forma incremental todos los productos que puedes vender, con tu precio de partner.
  • Pedidos: hasta 10 líneas × 9 unidades por petición; el total se descuenta de tu saldo al momento.
  • Entrega: claves, enlaces de Steam Gift, credenciales de cuenta o enlaces de activación, por API o webhook.
  • Reembolsos: las unidades que no se pudieron entregar se abonan automáticamente. Las claves, Steam Gifts, cuentas y enlaces entregados son definitivos: no se pueden devolver ni reembolsar.

Autenticación y entornos

Crea las claves en Panel → Partner → Claves API. Cada clave se muestra una sola vez; solo guardamos su hash. Envíala en la cabecera Authorization (también se acepta X-Api-Key).

curl https://buycheapkeys.com/partner-api/v1/ping \
  -H "Authorization: Bearer bck_test_xxxxxxxxxxxx_..."
PrefijoModoComportamiento
bck_test_SandboxCatálogo y precios reales, saldo de prueba separado (reiniciable), claves ficticias tipo TEST-AB12C-…, sin mover dinero. Los webhooks llegan con mode: test.
bck_live_ProducciónCompras reales cargadas a tu saldo real.
PermisoPermite
catalog:readGET /products, /products/{id}, /meta, /ping
orders:writePOST /orders
orders:readGET /orders, /orders/{id}, /orders/{id}/keys, POST /webhooks/test
balance:readGET /balance

Lista blanca de IPs opcional (IPv4/IPv6, CIDR) por cuenta. Las claves no caducan salvo que las revoques; para rotarlas crea una nueva y revoca la antigua.

Inicio rápido

1) Crea una clave bck_test_. 2) Lista productos. 3) Haz un pedido con ?wait=20 para recibirlo ya completado. 4) Descarga las claves.

curl "https://buycheapkeys.com/partner-api/v1/products?limit=100&page=1&inStock=true" \
  -H "Authorization: Bearer $BCK_API_KEY"

Catálogo y sincronización

GET /products devuelve hasta 100 productos ordenados por updatedAt (y luego id). updatedAt solo cambia cuando cambia algo relevante (precio, stock, nombre, región, textos, imágenes). Sincroniza con el cursor: cada respuesta trae nextCursor y hasMore; pasa nextCursor como ?cursor= hasta que hasMore sea false y guárdalo para la siguiente ejecución. Nunca salta ni repite productos, aunque muchos compartan marca de tiempo. page y updatedSince siguen disponibles para navegar. Filtros: inStock, platform, region, productType, deliveryType, search, ids (separados por comas, máx. 100).

curl "https://buycheapkeys.com/partner-api/v1/products?cursor=$SAVED_NEXT_CURSOR&includeRemoved=true&limit=100" \
  -H "Authorization: Bearer $BCK_API_KEY"

Recomendado: una sincronización completa (sin cursor) y después cada 5–15 minutos desde el nextCursor guardado, siempre con includeRemoved=true. Un producto con removed: true o inStock: false no debe venderse.

{
  "id": "prod-17298",
  "name": "Terraria (Steam Gift)",
  "platform": "Steam",
  "region": "Europe",
  "productType": "game",
  "deliveryType": "gift",
  "price": 3.71,
  "currency": "EUR",
  "inStock": true,
  "qty": 12,
  "activation": { "excludedCountries": ["RU", "BY", "..."], "allowedCountryCount": 53 },
  "coverImage": "https://buycheapkeys.com/api/media/catalog/category/.../cover.jpg",
  "screenshots": ["https://buycheapkeys.com/api/media/..."],
  "description": "Dig, Fight, Explore, Build...",
  "activationDetails": "You will receive a gift link...",
  "languages": ["English", "Spanish", "German"],
  "genres": ["Action", "Adventure"],
  "developer": "Re-Logic", "publisher": "Re-Logic", "releaseDate": "2011-05-16", "ageRating": "PEGI 12",
  "systemRequirements": [ { "system": "Windows", "requirement": ["..."] } ],
  "url": "https://buycheapkeys.com/en/product/terraria-steam-europe-238023",
  "updatedAt": "2026-10-01T16:05:12.881Z",
  "removed": false
}
CampoSignificado
nextCursor / hasMoreCampos de la respuesta para sincronizar: pasa nextCursor como ?cursor= mientras hasMore sea true; guarda el último para la siguiente ejecución.
priceTu precio por unidad en EUR. Se vuelve a comprobar en vivo al pedir.
deliveryTypekey = código para canjear · gift = enlace de Steam Gift · account = credenciales de cuenta · link = enlace de activación. Indícale a tu cliente qué compra.
region / activationRegión y la lista ISO exacta de países donde NO se puede activar (null = solo se conoce la región).
qtyUnidades aproximadas disponibles (máx. 99); null = desconocido.
coverImage / screenshotsServidas desde nuestro CDN; guárdalas en caché en tu lado.
activationDetailsInstrucciones de canje (en inglés) para mostrar a tu cliente.

Pedidos

POST /orders con externalId (tu referencia única) e items (productId, qty 1–9, maxUnitPrice). En cada línea comprobamos el precio en vivo: si supera maxUnitPrice se rechaza todo el pedido con PRICE_CHANGED y no se cobra nada. Si es menor, pagas el precio menor.

const res = await fetch("https://buycheapkeys.com/partner-api/v1/orders?wait=20", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.BCK_API_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": `shop-order-${order.id}`, // same value on every retry
  },
  body: JSON.stringify({
    externalId: String(order.id),
    items: [{ productId: "prod-17298", qty: 1, maxUnitPrice: 4.5 }],
  }),
});
const data = await res.json();
if (!res.ok) throw new Error(`${data.error.code}: ${data.error.message}`);
if (data.status === "completed") {
  const { keys } = await (await fetch(`https://buycheapkeys.com/partner-api/v1/orders/${data.id}/keys`, {
    headers: { Authorization: `Bearer ${process.env.BCK_API_KEY}` },
  })).json();
  // deliver keys[].value to your customer
}
  • Envía la cabecera Idempotency-Key (8–100 caracteres) y repítela al reintentar: recibes la respuesta original y nunca se cobra dos veces. externalId también es único por cuenta.
  • ?wait=N (0–25 s) espera a que termine antes de responder. Sin él, el pedido vuelve en processing y te avisamos por webhook o consultando GET /orders/{id}.
  • El total se descuenta al aceptar el pedido. Las unidades que no se puedan entregar se abonan automáticamente (refunded).
EstadoSignificado
processingPagado; se están comprando/entregando las claves (normalmente segundos; productos sin lanzar pueden tardar más).
completedTodas las unidades entregadas.
partially_completedParte entregada; el resto se ha abonado a tu saldo.
failedNo se pudo entregar nada; reembolsado por completo.

Entrega de claves

GET /orders/{id}/keys devuelve cada unidad entregada: value contiene el código, la URL del Steam Gift, las credenciales de la cuenta o el enlace de activación según deliveryType. contentType es text/plain o un tipo de imagen (entonces value va en base64).

Guarda las claves cifradas y muéstralas solo al comprador. La primera descarga de cada pedido queda registrada en nuestro lado como prueba de entrega.

Sin devoluciones

Cada unidad entregada (clave, enlace de Steam Gift, cuenta o enlace de activación) es definitiva: se compra al proveedor para ti en el momento de la entrega y no se puede devolver ni reembolsar, aunque no se haya canjeado. Solo se reembolsan, automáticamente, las unidades que no se pudieron entregar. Revisa la región, activation.excludedCountries y deliveryType antes de vender y muéstraselos a tu cliente.

Si una clave entregada no funciona, escribe a [email protected] en los 7 días siguientes con el id del pedido y una captura del error de activación. La reclamación se traslada al proveedor; solo habrá sustitución o abono si el proveedor sustituye o reembolsa esa clave.

Webhooks

Configura una URL https en Panel → Webhooks y recibirás un secreto de firma (whsec_…). Cada evento es un POST con las cabeceras X-BCK-Event, X-BCK-Delivery (id único: úsalo para descartar duplicados) y X-BCK-Signature: t=<unix>,v1=<hex> donde v1 = HMAC-SHA256(secreto, t + "." + cuerpo).

EventoCuándo
order.completedTodas las unidades entregadas.
order.partially_completedParte entregada y el resto reembolsado.
order.failedNada entregado, reembolso completo.
balance.creditedSe ha añadido una recarga a tu saldo.
webhook.testEnviado por POST /webhooks/test o el botón del panel.
{
  "id": "evt_4m2k9q7x1z8c3v5b6n0p",
  "event": "order.completed",
  "mode": "live",
  "createdAt": "2026-10-01T16:20:31.512Z",
  "data": { "id": "po_7f3k2m9q4x8z1c5v6b0n", "externalId": "shop-10045", "status": "completed", "total": 3.71, "...": "same object as GET /orders/{id}" }
}
  • Responde 2xx en menos de 8 s y procesa en segundo plano. No se siguen redirecciones.
  • Los envíos fallidos se reintentan tras 10 s, 30 s, 1 min, 5 min, 15 min, 30 min, 1 h, 2 h, 4 h, 6 h y 12 h (~26 h).
  • Los eventos pueden llegar desordenados o repetidos: ante la duda vuelve a leer GET /orders/{id}.

Errores

Los errores usan códigos HTTP y un code estable. Indica el requestId al contactar con soporte.

{
  "error": {
    "code": "PRICE_CHANGED",
    "message": "The price of prod-17298 is now 3.95 EUR, above your maxUnitPrice.",
    "details": { "productId": "prod-17298", "currentPrice": 3.95 },
    "requestId": "req_k3m9x2q8z7c1v4b6"
  }
}
codeHTTPSignificadoQué hacer
UNAUTHORIZED401Clave ausente, inválida, revocada o caducada.Revisa la clave o crea otra en el panel.
ACCOUNT_NOT_ACTIVE403Cuenta de partner pendiente, suspendida o rechazada.Contáctanos.
IP_NOT_ALLOWED403La IP no está en tu lista blanca.Añádela en Panel → Webhooks y seguridad.
INSUFFICIENT_SCOPE403La clave no tiene permiso para este endpoint.Crea una clave con ese permiso.
NOT_FOUND404Producto, pedido o ruta desconocidos.—
VALIDATION_ERROR400Cuerpo o parámetros inválidos (details indica cada campo).Corrige la petición; no la repitas igual.
INSUFFICIENT_BALANCE402Saldo insuficiente. No se ha cobrado nada.Recarga y reintenta.
PRICE_CHANGED409El precio real supera maxUnitPrice. No se ha cobrado nada.Actualiza el precio (details.currentPrice) y reintenta.
OUT_OF_STOCK409No hay unidades suficientes. No se ha cobrado nada.Reintenta más tarde u oculta el producto.
PRODUCT_UNAVAILABLE409Producto no vendible por API.Retíralo de tu tienda.
DUPLICATE_EXTERNAL_ID409externalId ya usado; details.orderId es el pedido existente.Consulta ese pedido.
IDEMPOTENCY_CONFLICT409Idempotency-Key reutilizada con otro cuerpo.Usa una clave nueva por pedido.
IDEMPOTENCY_IN_PROGRESS409La misma Idempotency-Key se está procesando.Reintenta en unos segundos.
ORDER_LIMIT_EXCEEDED422Total por encima de tu límite por pedido.Divide el pedido o pide un límite mayor.
DAILY_LIMIT_EXCEEDED422Límite de gasto de 24 h alcanzado.Espera o pide un límite mayor.
RATE_LIMITED429Demasiadas peticiones.Espera (details.retryAfterMs).
SERVICE_UNAVAILABLE503No se puede vender temporalmente. No se ha cobrado nada.Reintenta con espera exponencial.
INTERNAL_ERROR500Error inesperado (registrado con requestId).Reintenta con la misma Idempotency-Key.

Límites

LímiteValor
Peticiones por clave20 / segundo y 600 / minuto
Pedidos por cuenta120 / minuto
Descargas de claves por cuenta300 / minuto
Líneas por pedido / unidades por línea10 / 9
Importe por pedido y gasto en 24 hPor cuenta (ver Panel → Resumen); pídenos ampliarlos
Tamaño de página100 productos o pedidos

Saldo y recargas

GET /balance devuelve el saldo del modo de la clave. Recarga desde Panel → Saldo: recibes una referencia única para indicar en la transferencia; el importe se abona al recibirlo (e-mail + webhook balance.credited). Todos los movimientos aparecen en el extracto.

Implementarlo con una IA / ejemplo completo

Documentación legible por máquinas: https://buycheapkeys.com/developers.es.md (esta página en Markdown), https://buycheapkeys.com/developers.md (inglés), la especificación OpenAPI 3.1 https://buycheapkeys.com/partner-api/v1/openapi.json y https://buycheapkeys.com/llms.txt. Pásale estas URLs a tu asistente de IA junto con el prompt de abajo.

Integración de referencia completa (Node.js 18+, sin dependencias): https://buycheapkeys.com/developers/bck-partner-client.mjs — sincronización del catálogo con cursor, pedidos seguros con reintentos e idempotencia, descarga de claves y un receptor de webhooks con verificación de firma.

curl -O https://buycheapkeys.com/developers/bck-partner-client.mjs
export BCK_API_KEY=bck_test_...   # clave sandbox de Panel → Partner → Claves API
node bck-partner-client.mjs balance
node bck-partner-client.mjs sync
node bck-partner-client.mjs order <productId> 1 <maxUnitPrice>
  • Regla 1 — vende solo productos con inStock=true y removed=false; resincroniza cada 5–15 min desde el nextCursor guardado.
  • Regla 2 — un pedido de cliente = un externalId = una Idempotency-Key; reutiliza ambos en cada reintento.
  • Regla 3 — envía siempre maxUnitPrice; los errores 4xx de negocio son definitivos y no se ha cobrado nada.
  • Regla 4 — reintenta solo errores de red, 429, 5xx e IDEMPOTENCY_IN_PROGRESS, con espera exponencial.
  • Regla 5 — un pedido en processing ya está pagado: espera al webhook o consulta GET /orders/{id}; nunca lo repitas.
  • Regla 6 — guarda la clave API en el servidor; verifica la firma de los webhooks; muestra al cliente el deliveryType y la región de activación.

Lista de seguridad

  • Guarda las claves API solo en tu servidor (nunca en navegadores ni apps), en variables de entorno o un gestor de secretos.
  • Usa claves distintas por sistema y con los permisos mínimos; activa la lista blanca de IPs.
  • Envía siempre maxUnitPrice y una Idempotency-Key.
  • Verifica la firma y la marca de tiempo de cada webhook antes de fiarte de él.
  • Si sospechas una filtración, crea claves nuevas, rota el secreto del webhook y revoca las antiguas.
Documentación de la API para partners | BuyCheapKeys