-20 %

Windows y Office con 20 % de descuento

BuyCheapKeys

API de partners de BuyCheapKeys

API REST/JSON para vender claves de Windows y Office en tu propia web. Cada pedido se paga con tu saldo prepago y las claves llegan en la misma respuesta, compradas al vendedor más barato con stock en ese momento.

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: las claves vienen en la respuesta del pedido y se pueden volver a leer con GET /orders/{id}/keys.
  • Reclamaciones: una clave defectuosa se puede reclamar durante 14 días desde tu panel de partner, con mensajes y capturas. Una clave de sustitución llega sola a tu pedido y un reembolso vuelve a tu saldo.

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, /me, /ping, /gift-cards
webhooks:writePUT y DELETE /webhook (registrar o quitar tu URL de webhook)
orders:writePOST /orders, POST /gift-cards/orders
orders:readGET /orders, /orders/{id}, /orders/{id}/keys, /gift-cards/orders, /gift-cards/orders/{id}, 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: vuelve completado y con las claves. 4) Vuelve a leer las claves cuando quieras con GET /orders/{id}/keys. Las cuentas de partner que aún se están aprobando pueden usar claves sandbox.

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 en stock (máx. 999).
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. Código promocional: añade couponCode: MICROSOFT20 al cuerpo del pedido para pagar un 20 % menos en los productos Microsoft mientras la promoción esté activa (maxUnitPrice se compara con el precio ya rebajado; un código desconocido o una promoción terminada devuelve INVALID_COUPON y no se cobra nada).

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.
  • El pedido se completa en la misma petición: la respuesta trae estado completed y un array keys. Una petición repetida (misma Idempotency-Key) devuelve el pedido sin las claves y con keysOmitted: true: léelas con GET /orders/{id}/keys.
  • Si no hay stock o tu saldo no alcanza no se cobra nada ni se usa ninguna clave (OUT_OF_STOCK, INSUFFICIENT_BALANCE). maxUnitPrice es un tope para cada clave; una línea puede dividirse en varios items si hacen falta vendedores con precios distintos.
  • Si una petición agota el tiempo, envíala otra vez con el mismo externalId: recibes DUPLICATE_EXTERNAL_ID con el id del pedido y puedes leer sus claves.
EstadoSignificado
completedTodas las unidades entregadas. Las claves vienen en la respuesta.
partially_refundedAlgunas claves se reembolsaron a tu saldo tras reclamaciones.
refundedTodas las claves del pedido se reembolsaron a tu saldo.

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.

Reclamaciones y reembolsos

Cada clave viene de un vendedor al que se paga tras un periodo de retención, así que una clave defectuosa se puede reclamar durante 14 días. Abre el pedido en Panel → Pedidos (API), elige la clave, escribe al vendedor y adjunta capturas del error de activación. El vendedor puede enviar una clave de sustitución (aparece en tu pedido y recibes el webhook key.replaced) o reembolsar la clave (el precio vuelve a tu saldo de la API una sola vez y recibes order.refunded). Si no estás de acuerdo, escala y decide BuyCheapKeys.

Revisa la región, excludedCountries y el tipo de licencia antes de vender y muéstraselos a tu cliente. Un reembolso a tu saldo no reembolsa a tu propio cliente: eso lo decides tú.

Tarjetas regalo BuyCheapKeys en bloque

Compra nuestras propias tarjetas regalo para revenderlas: códigos BCK-XXXX-XXXX-XXXX-XXXX que suman su valor a la Wallet de BuyCheapKeys de quien los canjea en buycheapkeys.com/wallet. GET /gift-cards devuelve los importes a la venta, los descuentos por volumen, los máximos por pedido y el saldo de tu Wallet. POST /gift-cards/orders compra N tarjetas de un mismo importe y devuelve los códigos al momento; GET /gift-cards/orders/{id} los vuelve a mostrar con el estado de cada código.

curl https://buycheapkeys.com/partner-api/v1/gift-cards \
  -H "Authorization: Bearer $BCK_API_KEY"
  • Se paga solo con la Wallet de BuyCheapKeys de tu cuenta de la tienda (recárgala en buycheapkeys.com/wallet), no con el saldo de la API. Precio = valor facial menos el descuento por volumen de esa cantidad.
  • Los importes, descuentos y máximos pueden cambiar: envía maxTotal para rechazar un total mayor (PRICE_CHANGED, sin cobro). Idempotency-Key y el externalId único funcionan igual que en los pedidos.
  • Venta en pausa: PRODUCT_UNAVAILABLE (409). Importe que no se vende o cantidad fuera de rango: VALIDATION_ERROR. Pedido demasiado grande: ORDER_LIMIT_EXCEEDED. Saldo insuficiente en la Wallet: INSUFFICIENT_BALANCE (402).
  • Las claves de sandbox devuelven códigos falsos BCK-TEST-… que no se pueden canjear y no cobran nada.
  • Los códigos vendidos son definitivos. Cada código caduca (expiresAt) y tiene límites de canje por cuenta. Un código que bloqueemos por fraude deja de mostrarse (code: null, estado blocked). Guarda los códigos cifrados.

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.completedUn pedido se ha completado.
order.refundedUna reclamación acabó en reembolso a tu saldo (`refundedSale`, `amount`).
product.updatedHa cambiado el precio, el stock o la ficha de un producto (`data.product` trae el producto completo, `removed: true` si se retira).
key.replacedUn vendedor sustituyó una clave: `oldKeyId`, `newKeyId`; lee la nueva con GET /orders/{id}/keys.
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.
INVALID_COUPON400couponCode desconocido o promoción terminada. No se ha cobrado nada.Quita el código o envía el vigente (MICROSOFT20).
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 — nunca repitas un pedido tras un timeout: repite el mismo externalId y lee las claves del pedido existente.
  • 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.