Blume Developer API
Integre Blume con apps externas, canales B2B, ERPs, inventario, clientes, pedidos y carritos abandonados usando una API REST simple, versionada y lista para producción.
curl -X POST "https://xapi.madebyblume.com/v1/developer/auth/token" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=client_credentials" \
-d "client_id=$BLUME_CLIENT_ID" \
-d "client_secret=$BLUME_CLIENT_SECRET" \
-d "scope=catalog:read locations:read carts:read customers:read orders:read discounts:read"
const params = new URLSearchParams({
grant_type: "client_credentials",
client_id: process.env.BLUME_CLIENT_ID,
client_secret: process.env.BLUME_CLIENT_SECRET,
scope: "catalog:read locations:read customers:read orders:read"
});
const res = await fetch("https://xapi.madebyblume.com/v1/developer/auth/token", {
method: "POST",
headers: { "Content-Type": "application/x-www-form-urlencoded" },
body: params
});
const token = await res.json();
console.log(token.access_token);
using var client = new HttpClient();
var body = new Dictionary<string, string>
{
["grant_type"] = "client_credentials",
["client_id"] = Environment.GetEnvironmentVariable("BLUME_CLIENT_ID")!,
["client_secret"] = Environment.GetEnvironmentVariable("BLUME_CLIENT_SECRET")!,
["scope"] = "catalog:read locations:read customers:read orders:read"
};
var res = await client.PostAsync(
"https://xapi.madebyblume.com/v1/developer/auth/token",
new FormUrlEncodedContent(body));
res.EnsureSuccessStatusCode();
var json = await res.Content.ReadAsStringAsync();
Overview
Lo esencial para empezar.
La Blume Developer API está pensada para aplicaciones externas que necesitan leer catálogo, consultar inventario por ubicación, leer y crear clientes, leer y crear pedidos, verificar descuentos y actualizar estados operativos sin entrar al admin.
Quickstart
Haga la primera llamada en 5 minutos.
POST
/v1/developer/auth/token
Obtenga un access token y úselo para consultar el catálogo.
/v1/developer/auth/token
Obtenga un access token y úselo para consultar el catálogo.
- Cree credenciales desde Configuración → Developer API en el admin.
- Solicite un token con
grant_type=client_credentials. - Incluya el token en cada request autenticado.
TOKEN=$(curl -s -X POST "https://xapi.madebyblume.com/v1/developer/auth/token" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=client_credentials" \
-d "client_id=$BLUME_CLIENT_ID" \
-d "client_secret=$BLUME_CLIENT_SECRET" \
-d "scope=catalog:read" | jq -r .access_token)
curl "https://xapi.madebyblume.com/v1/developer/catalog/products?brand=Nike" \
-H "Authorization: Bearer $TOKEN"
Authentication
Autenticación con client credentials.
El endpoint de token no requiere Bearer token. Todos los demás endpoints requieren un token válido.
POST
/v1/developer/auth/token
Intercambia client_id y client_secret por un access token.
/v1/developer/auth/token
Intercambia client_id y client_secret por un access token.
| Campo | Tipo | Requerido | Descripción |
|---|---|---|---|
grant_type |
string |
Sí | Debe ser client_credentials. |
client_id |
string |
Sí | Identificador generado en el admin de Blume. |
client_secret |
string |
Sí | Se muestra una sola vez al crear o rotar credenciales. |
scope |
string |
No | Scopes separados por espacio. Si se omite, se intentan conceder los scopes permitidos al cliente. |
curl -X POST "https://xapi.madebyblume.com/v1/developer/auth/token" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=client_credentials" \
-d "client_id=blume_live_xxxxx" \
-d "client_secret=blume_secret_xxxxx" \
-d "scope=catalog:read locations:read carts:read customers:read orders:read discounts:read"
{
"access_token": "eyJhbGciOiJIUzI1NiIs...",
"token_type": "Bearer",
"expires_in": 86400,
"scope": "catalog:read locations:read",
"companyId": "company-guid",
"clientId": "blume_live_xxxxx"
}
Scopes
Solicite solo los permisos que necesita.
| Scope | Permite | Endpoints principales |
|---|---|---|
catalog:read |
Leer catálogo, detalle de productos e inventario. | /catalog/* |
locations:read |
Leer ubicaciones y productos por ubicación. | /locations/* |
carts:read |
Leer resumen, lista y detalle de carritos abandonados. | /carts/* |
customers:read |
Listar clientes, consultar detalle y verificar si un cliente existe. | /customers/* |
customers:write |
Crear clientes y direcciones. | /customers |
orders:read |
Listar pedidos y consultar detalle con cliente, dirección, totales e items. | /orders |
orders:write |
Crear pedidos, actualizar estados permitidos y actualizar líneas de un pedido. | /orders |
discounts:read |
Verificar descuentos activos usando la misma lógica del carrito/checkout. | /discounts/verify |
emails:send |
Enviar emails transaccionales con plantillas aprobadas para la compañía. | /emails/* |
giftcards:read |
Verificar tarjetas de regalo sin consumirlas. | /gift-cards/verify |
giftcards:write |
Verificar y canjear tarjetas de regalo. | /gift-cards/* |
Webhooks
Eventos para integraciones instaladas.
Para recibir eventos en tiempo real, instale y configure la app/integración
correspondiente desde el admin de Blume. La app define el webhookUrl,
el secreto de firma y los eventos habilitados.
POST
Webhook URL configurado en la appBlume envía eventos
al endpoint configurado en la instalación de la app.
Webhook URL configurado en la appBlume envía eventos
al endpoint configurado en la instalación de la app.Los webhooks usan application/json. El
receptor debe responder con status 2xx para considerar el evento
entregado. Si falla, Blume reintenta automáticamente con backoff.
| Header | Descripción |
|---|---|
X-Blume-Event-Id |
Identificador único del evento. Úselo para idempotencia. |
X-Blume-Topic |
Nombre del evento, por ejemplo order.created. |
X-Blume-Timestamp |
Unix timestamp en segundos usado para la firma. |
X-Blume-Signature |
Firma HMAC-SHA256. Se envía como sha256=<hex> cuando la app tiene
signingSecret configurado. |
La firma se calcula sobre el body crudo, antes de parsear JSON:
import crypto from "crypto";
function verifyBlumeSignature({ rawBody, timestamp, signature, secret }) {
const payload = `${timestamp}.${rawBody}`;
const expected =
"sha256=" +
crypto.createHmac("sha256", secret).update(payload, "utf8").digest("hex");
return crypto.timingSafeEqual(
Buffer.from(expected),
Buffer.from(signature || "")
);
}
EVENTS
Topics soportadosEventos disponibles para apps de
integración.
Topics soportadosEventos disponibles para apps de
integración.| Topic | Cuándo se envía |
|---|---|
order.created |
Cuando se crea un pedido. |
order.paid |
Cuando un pedido queda pagado. |
order.cancelled |
Cuando un pedido se cancela o rechaza. |
cart.abandoned |
Cuando un carrito con contacto capturado pasa a abandonado. |
cart.recovered |
Cuando un carrito abandonado se recupera y termina en orden. |
JSON
Envelope del eventoTodos los eventos usan la misma
estructura base.
Envelope del eventoTodos los eventos usan la misma
estructura base.{
"eventId": "evt_01J2XYZABC123",
"topic": "order.created",
"companyId": "company-guid",
"createdAt": "2026-06-23T18:30:00Z",
"source": "blume",
"productMatchKey": "externalId",
"data": {}
}
productMatchKey indica cómo debe la
integración relacionar productos. El valor recomendado y predeterminado es externalId. Si la empresa lo configura, también puede ser barcode.
EXAMPLE
order.createdEjemplo de payload para un pedido
creada.
order.createdEjemplo de payload para un pedido
creada.{
"eventId": "evt_01J2XYZABC123",
"topic": "order.created",
"companyId": "company-guid",
"createdAt": "2026-06-23T18:30:00Z",
"source": "blume",
"productMatchKey": "externalId",
"data": {
"orderId": "8123",
"orderNumber": 1044,
"urlCode": "order-url-guid",
"status": "pending",
"internalStatus": "created",
"paymentStatus": "pending",
"placedAt": "2026-06-23T18:29:55Z",
"paidAt": null,
"currency": "CRC",
"subtotal": 25000,
"discount": 0,
"tax": 0,
"shippingCost": 2500,
"totalAmount": 27500,
"paymentMethod": "moneytransfer",
"couponCode": "",
"channel": "web",
"customer": {
"customerId": "customer-guid",
"fullName": "María Rodríguez",
"email": "[email protected]",
"phone": "88888888",
"documentId": "1-1111-1111"
},
"shippingAddress": {
"type": "shipping",
"methodType": "delivery",
"methodName": "Envío estándar",
"country": "Costa Rica",
"state": "San José",
"city": "Escazú",
"postalCode": "10201",
"coordinates": "9.9325,-84.0796",
"locationDescription": "Frente al parque",
"status": "created",
"trackingNumber": ""
},
"lineItems": [
{
"itemId": "10001",
"productId": 12345,
"externalId": 12345,
"barcode": "7440000000000",
"referenceCode": "ABC123",
"colorCode": "001",
"name": "Producto ejemplo",
"description": "Producto ejemplo",
"quantity": 1,
"unitPrice": 25000,
"lineTotal": 25000,
"imageUrl": "https://...",
"isDiscountPrice": false
}
]
}
}
Response format
Formato consistente de respuesta.
Los endpoints autenticados responden con el mismo sobre de respuesta para facilitar integración y manejo de errores.
{
"success": true,
"data": {
"id": 123,
"status": "created"
},
"error": null,
"meta": null
}
{
"success": false,
"data": null,
"error": {
"code": "ORDER_VALIDATION_FAILED",
"message": "The subtotal or total does not match."
},
"meta": null
}
Errors
Códigos de estado y errores comunes.
| Status | Cuándo ocurre | Qué hacer |
|---|---|---|
200 |
Solicitud exitosa. | Leer data. |
400 |
Body inválido, campos requeridos faltantes o validación fallida. | Revise error.code y error.message. |
401 |
Credenciales inválidas o token faltante/expirado. | Solicite un token nuevo. |
403 |
El token no tiene el scope requerido. | Solicite scopes adicionales desde el admin. |
404 |
Recurso no encontrado para la compañía del token. | Valide IDs externos y pertenencia al comercio. |
409 |
Intento de crear un recurso que ya existe. | Use verify primero o maneje el registro existente. |
Las llamadas de token se registran como no facturables. Las llamadas de negocio se registran por cliente, comercio y endpoint para métricas de uso.
API reference
Endpoints disponibles.
/v1/developer/catalog/productsLista
productos con filtros simples./v1/developer/catalog/products/searchLista
productos con filtros en JSON./v1/developer/catalog/products/expandDetalle
de producto por referencia y color./v1/developer/catalog/products/{externalId}/availabilityInventario
por ubicación./v1/developer/catalog/products/{externalId}/nearest-locationsUbicaciones
cercanas con stock del producto./v1/developer/customersLista clientes
con métricas básicas./v1/developer/customers/{customerId}Detalle
de cliente, métricas y direcciones./v1/developer/customers/verifyVerifica
cliente existente./v1/developer/customersCrea un
cliente./v1/developer/customers/{customerId}/addressesCrea
dirección para un cliente./v1/developer/carts/summaryResumen de
carritos abandonados, valor potencial y recuperación./v1/developer/carts/abandonedLista
carritos abandonados filtrables./v1/developer/carts/{cartId}Detalle de
carrito con productos y recovery URL./v1/developer/ordersLista pedidos con
filtros básicos./v1/developer/orders/{orderId}Detalle de
orden con cliente, dirección, totales e items./v1/developer/ordersCrea un pedido
retail./v1/developer/orders/{orderId}/statusActualiza
estados permitidos./v1/developer/orders/items/updateReemplaza
líneas y totales de un pedido./v1/developer/discounts/verifyVerifica
un descuento activo por código./v1/developer/discounts/verifyVerifica
un descuento contra items del carrito./v1/developer/emails/template/sendEnvía
email con plantilla aprobada./v1/developer/gift-cards/verifyVerifica
una tarjeta de regalo./v1/developer/gift-cards/useCanjea una
tarjeta de regalo válida./v1/developer/locationsLista ubicaciones
configuradas./v1/developer/locations/nearestUbicaciones
cercanas por coordenadas./v1/developer/locations/{externalWarehouseId}/productsProductos
con stock en una ubicación.Para integraciones que reciben eventos en tiempo real por webhook, instale y configure la app correspondiente desde el admin de Blume, por ejemplo Hilo u Odoo.
Catalog
Productos e inventario.
Use estos endpoints para listar productos, expandir detalle y consultar stock
por local o bodega. Para integraciones, externalId es el
identificador recomendado por defecto; barcode se devuelve como
identificador alternativo cuando esté configurado.
GET
/v1/developer/catalog/productsLista productos
visibles usando query params o tokens filter.
/v1/developer/catalog/productsLista productos
visibles usando query params o tokens filter.Filtros soportados: brand, color, model, style, productType, size, gender, family, subFamily y campos
custom.
curl "https://xapi.madebyblume.com/v1/developer/catalog/products?brand=Nike&family=Zapatos" \
-H "Authorization: Bearer $TOKEN"
POST
/v1/developer/catalog/products/searchVersión JSON
para filtros más cómodos desde backend.
/v1/developer/catalog/products/searchVersión JSON
para filtros más cómodos desde backend.{
"filters": [
"brand=Nike",
"family=Zapatos",
"gender=Mujer"
]
}
{
"success": true,
"data": [
{
"referenceCode": "ABC123",
"colorCode": "001",
"title": "Tênis ejemplo",
"brand": "Nike",
"price": 59900,
"discountPrice": 49900,
"externalId": 12345,
"barcode": "7440000000000",
"images": ["https://..."]
}
]
}
POST
/v1/developer/catalog/products/expandObtiene
tallas, imágenes y variaciones de color por producto.
/v1/developer/catalog/products/expandObtiene
tallas, imágenes y variaciones de color por producto.{
"referenceCode": "ABC123",
"colorCode": "001"
}
La respuesta incluye products, images y colorVariations. Cada
producto puede incluir externalId, barCode y barcode.
GET
/v1/developer/catalog/products/{externalId}/availabilityConsulta stock total y
por ubicación/bodega.
/v1/developer/catalog/products/{externalId}/availabilityConsulta stock total y
por ubicación/bodega.Usa Product.ExternalId, WarehouseStock.ExternalProductId y StoreLocation.ExternalWarehouseId para responder con stock por
ubicación.
{
"success": true,
"data": {
"externalId": 12345,
"barcode": "7440000000000",
"referenceCode": "ABC123",
"colorCode": "001",
"title": "Producto ejemplo",
"productStock": 18,
"totalAvailable": 18,
"available": true,
"locations": [
{
"storeLocationId": 7,
"externalWarehouseId": 20,
"name": "Escazú",
"coordinates": "9.9325,-84.0796",
"amount": 5,
"available": true
}
]
}
}
GET
/v1/developer/catalog/products/{externalId}/nearest-locationsUbicaciones
cercanas que tienen stock suficiente para un producto.
/v1/developer/catalog/products/{externalId}/nearest-locationsUbicaciones
cercanas que tienen stock suficiente para un producto.curl "https://xapi.madebyblume.com/v1/developer/catalog/products/12345/nearest-locations?latitude=9.9325&longitude=-84.0796&quantity=1&maxResults=5" \
-H "Authorization: Bearer $TOKEN"
No requiere Google Maps cuando el cliente envía latitud/longitud. La cercanía se calcula por distancia geográfica.
Customers
Clientes y direcciones.
GET
/v1/developer/customersLista clientes con datos de
contacto y métricas básicas.
/v1/developer/customersLista clientes con datos de
contacto y métricas básicas.Filtros soportados: search y limit.
curl "https://xapi.madebyblume.com/v1/developer/customers?search=maria&limit=50" -H "Authorization: Bearer $TOKEN"
{
"success": true,
"data": {
"count": 1,
"limit": 50,
"customers": [
{
"customerId": "customer-guid",
"fullName": "María Rodríguez",
"email": "[email protected]",
"phone": "88888888",
"createdAt": "2026-06-11T10:00:00",
"metrics": {
"totalOrders": 4,
"totalSpent": 120000,
"averageOrderValue": 30000,
"lastOrderAt": "2026-06-10T14:00:00",
"daysSinceLastOrder": 1
}
}
]
}
}
GET
/v1/developer/customers/{customerId}Detalle de
cliente con métricas y direcciones.
/v1/developer/customers/{customerId}Detalle de
cliente con métricas y direcciones.curl "https://xapi.madebyblume.com/v1/developer/customers/customer-guid" -H "Authorization: Bearer $TOKEN"
La respuesta incluye datos de contacto, newsletter, métricas de compra y direcciones guardadas.
POST
/v1/developer/customers/verifyVerifica si un
cliente existe y devuelve su customerId.
/v1/developer/customers/verifyVerifica si un
cliente existe y devuelve su customerId.{
"email": "[email protected]",
"documentId": "1-1111-1111",
"phone": "88888888"
}
{
"success": true,
"data": {
"exists": true,
"customerId": "customer-guid",
"matchedBy": "email"
}
}
POST
/v1/developer/customersCrea un cliente. Si ya
existe, responde 409 Conflict.
/v1/developer/customersCrea un cliente. Si ya
existe, responde 409 Conflict.{
"fullName": "María Rodríguez",
"documentId": "1-1111-1111",
"email": "[email protected]",
"phone": "88888888",
"subscribedNewsletter": true
}
{
"success": true,
"data": {
"customerId": "customer-guid",
"created": true
}
}
POST
/v1/developer/customers/{customerId}/addressesCrea
una dirección para el cliente.
/v1/developer/customers/{customerId}/addressesCrea
una dirección para el cliente.{
"isDefault": true,
"country": "Costa Rica",
"state": "San José",
"city": "Escazú",
"zipCode": "10201",
"coordinates": "9.9325,-84.0796",
"locationDescription": "Frente al parque, casa azul."
}
Si isDefault es true, las direcciones previas del cliente se marcan como no
predeterminadas.
Carts
Carritos abandonados.
Use estos endpoints para consultar carritos abandonados, productos, contacto capturado, paso donde el cliente abandonó y enlaces de recuperación.
GET
/v1/developer/carts/summaryResumen de carritos
abandonados y recuperación para el comercio del token.
/v1/developer/carts/summaryResumen de carritos
abandonados y recuperación para el comercio del token.curl "https://xapi.madebyblume.com/v1/developer/carts/summary?range=7d" \
-H "Authorization: Bearer $TOKEN"
{
"success": true,
"data": {
"range": "7d",
"activeCount": 8,
"abandonedCount": 18,
"recoveredCount": 4,
"potentialRevenue": 420000,
"recoveredRevenue": 95000,
"recoveryRate": 22.22,
"emailSentCount": 12
}
}
GET
/v1/developer/carts/abandonedLista carritos
abandonados con contacto, totales y productos.
/v1/developer/carts/abandonedLista carritos
abandonados con contacto, totales y productos.Filtros soportados: status, hasPhone, hasEmail, abandonedSince, updatedSince
y limit.
curl "https://xapi.madebyblume.com/v1/developer/carts/abandoned?hasPhone=true&updatedSince=2026-06-11T00:00:00&limit=50" \
-H "Authorization: Bearer $TOKEN"
{
"success": true,
"data": {
"count": 1,
"limit": 50,
"carts": [
{
"cartId": "123",
"status": "abandoned",
"checkoutStep": "payment",
"customerName": "María Rodríguez",
"customerEmail": "[email protected]",
"customerPhoneE164": "+50688888888",
"abandonedAt": "2026-06-11T10:35:00",
"total": 27500,
"currency": "CRC",
"recoveryUrl": "https://store.com/checkout/recover/...",
"items": [
{
"productId": 12345,
"barcode": "7440000000000",
"referenceCode": "ABC123",
"colorCode": "001",
"description": "Producto ejemplo",
"quantity": 1,
"unitPrice": 25000,
"lineTotal": 25000,
"imageUrl": "https://..."
}
]
}
]
}
}
GET
/v1/developer/carts/{cartId}Detalle completo de un
carrito específico.
/v1/developer/carts/{cartId}Detalle completo de un
carrito específico.curl "https://xapi.madebyblume.com/v1/developer/carts/123" \
-H "Authorization: Bearer $TOKEN"
La respuesta incluye contacto capturado, timestamps, totales,
recoveryUrl, UTMs/referrer e items del carrito.
Orders
Pedidos, detalle y estados.
La creación de pedidos usa el mismo flujo validado del checkout retail. La
lectura devuelve cliente, dirección, totales e items con externalId y
barcode cuando está disponible.
GET
/v1/developer/ordersLista pedidos con filtros
básicos.
/v1/developer/ordersLista pedidos con filtros
básicos.Filtros soportados: customerId, status, paymentStatus, placedSince y limit.
curl "https://xapi.madebyblume.com/v1/developer/orders?paymentStatus=complete&limit=50" -H "Authorization: Bearer $TOKEN"
{
"success": true,
"data": {
"count": 1,
"limit": 50,
"orders": [
{
"orderId": "8123",
"orderNumber": 1044,
"customerId": "customer-guid",
"status": "paid",
"internalStatus": "created",
"paymentStatus": "complete",
"placedAt": "2026-06-11T10:00:00",
"paidAt": "2026-06-11T10:05:00",
"totalAmount": 27500,
"currency": "CRC"
}
]
}
}
GET
/v1/developer/orders/{orderId}Detalle de orden con
cliente, dirección, totales e items.
/v1/developer/orders/{orderId}Detalle de orden con
cliente, dirección, totales e items.curl "https://xapi.madebyblume.com/v1/developer/orders/8123" -H "Authorization: Bearer $TOKEN"
{
"productId": 12345,
"externalId": 12345,
"barcode": "7440000000000",
"referenceCode": "ABC123",
"colorCode": "001",
"name": "Producto ejemplo",
"quantity": 1,
"unitPrice": 25000,
"lineTotal": 25000
}
POST
/v1/developer/ordersCrea un pedido retail para la
tienda asociada al token.
/v1/developer/ordersCrea un pedido retail para la
tienda asociada al token.{
"customer": {
"fullName": "María Rodríguez",
"documentId": "1-1111-1111",
"email": "[email protected]",
"phone": "88888888"
},
"address": {
"country": "Costa Rica",
"state": "San José",
"city": "Escazú",
"locationDescription": "Frente al parque",
"coordinates": "9.9325,-84.0796"
},
"order": {
"deliveryMethod": "Envío estándar",
"deliveryType": "delivery",
"paymentMethod": "moneytransfer",
"currency": "CRC",
"subtotal": 25000,
"deliveryCost": 2500,
"discount": 0,
"tax": 0,
"total": 27500,
"items": [
{
"productId": 12345,
"description": "Producto ejemplo",
"quantity": 1,
"unitPrice": 25000,
"total": 25000,
"isDiscountPrice": false
}
]
},
"transactionLog": {
"paymentMethod": "moneytransfer",
"clientIp": "190.0.0.1"
}
}
{
"success": true,
"data": {
"id": 8123,
"total": 27500,
"urlCode": "order-url-guid",
"isGiftCard": false
}
}
PATCH
/v1/developer/orders/{orderId}/statusActualiza uno
de los estados públicos permitidos.
/v1/developer/orders/{orderId}/statusActualiza uno
de los estados públicos permitidos.| deliveryStatus | Efecto interno | |
|---|---|---|
enproceso |
Orden en preparación. | Sí, si sendEmail es true. |
facturado |
Pago completo y orden facturada. | Sí, si sendEmail es true. |
rechazado |
Pago rechazado / orden cancelada. | No envía email. |
entregadocte |
Entregado al cliente. | Sí, si sendEmail es true. |
entregadomsj |
En tránsito con mensajero. Requiere entrega. | Sí, si sendEmail es true. |
{
"deliveryStatus": "facturado",
"trackingNumber": "ABC123",
"sendEmail": true
}
{
"success": true,
"data": {
"orderId": 8123,
"number": 1044,
"urlCode": "order-url-guid",
"status": "created",
"paymentStatus": "complete",
"deliveryStatus": "created",
"trackingNumber": "ABC123",
"emailSent": true
}
}
POST
/v1/developer/orders/items/updateReemplaza las
líneas de un pedido y actualiza subtotal, descuento y total.
/v1/developer/orders/items/updateReemplaza las
líneas de un pedido y actualiza subtotal, descuento y total.Este endpoint reemplaza el flujo legacy de ASP orderItemUpdate. El campo orderNumber conserva el nombre legacy, pero debe contener el
Order.Id interno de Blume.
{
"storeName": "cachos",
"orderNumber": "8123",
"subtotal": 24000,
"discount": 1000,
"total": 23000,
"items": [
{
"description": "Zapato negro",
"productId": 12345,
"quantity": 1,
"unitPrice": 24000,
"total": 24000,
"isDiscountPrice": false
}
]
}
{
"success": true,
"data": {
"apiStatus": "approved",
"isApproved": true,
"data": {
"orderNumber": "8123",
"subtotal": 24000,
"discount": 1000,
"total": 23000,
"items": []
}
}
}
Discounts
Verificación de descuentos.
Estos endpoints usan la misma lógica de descuentos que el carrito y checkout de storefront.
GET
/v1/developer/discounts/verifyVerifica si un
descuento manual está activo por código.
/v1/developer/discounts/verifyVerifica si un
descuento manual está activo por código.curl "https://xapi.madebyblume.com/v1/developer/discounts/verify?code=WELCOME10" -H "Authorization: Bearer $TOKEN"
{
"success": true,
"data": {
"isValid": true,
"code": "WELCOME10",
"discountAmount": 0,
"discount": {
"discountId": 10,
"code": "WELCOME10",
"name": "Bienvenida",
"type": "percent",
"applyTo": "subtotal",
"value": 10,
"validUntil": "2026-12-31T23:59:59"
}
}
}
POST
/v1/developer/discounts/verifyVerifica el
descuento contra los items del carrito y calcula monto aplicable.
/v1/developer/discounts/verifyVerifica el
descuento contra los items del carrito y calcula monto aplicable.{
"code": "WELCOME10",
"items": [
{
"productId": 12345,
"description": "Producto ejemplo",
"quantity": 1,
"unitPrice": 25000,
"total": 25000,
"isDiscountPrice": false
}
]
}
Use esta versión cuando necesite validar reglas por subtotal, cantidad de items o productos aplicables.
Emails
Emails con plantillas aprobadas.
Use este endpoint para eventos externos como compras en tienda física, cashback,
encuestas u otras notificaciones operativas. Si no envía templateId,
se usa la plantilla actual de cashback.
POST
/v1/developer/emails/template/sendEnvía un email
usando una plantilla aprobada para la compañía.
/v1/developer/emails/template/sendEnvía un email
usando una plantilla aprobada para la compañía.{
"templateId": "d-aebc802e5344497a9e085b68bdf8bf51",
"fromName": "Plusshop Cashback",
"customer": {
"name": "Ana Cliente",
"email": "[email protected]",
"phone": "8888-8888",
"documentId": "1-1111-1111"
},
"store": {
"chain": "plusshop",
"name": "Tienda Escazú"
},
"order": {
"number": "F001-100",
"subtotal": "24000",
"discount": "0",
"tax": "0",
"total": "24000",
"cashback": "1200",
"cashbackRedeem": "0",
"items": [
{ "description": "Compra en tienda", "unitPrice": "24000", "quantity": "1", "total": "24000" }
]
}
}
{
"success": true,
"data": {
"apiStatus": "success",
"isApproved": true
}
}
Tarjetas de regalo
Verificación y canje.
Estos endpoints reemplazan el flujo legacy de ICG usando Bearer token y scopes.
La respuesta mantiene apiStatus e isApproved para facilitar migración.
GET
/v1/developer/gift-cards/verifyVerifica una gift
card sin marcarla como usada.
/v1/developer/gift-cards/verifyVerifica una gift
card sin marcarla como usada.curl "https://xapi.madebyblume.com/v1/developer/gift-cards/verify?code=ABCD1234&usedPlace=POPS%20Escazu" \
-H "Authorization: Bearer $BLUME_TOKEN"
{
"success": true,
"data": {
"apiStatus": "approved",
"isApproved": true,
"data": {
"orderNumber": 1044,
"id": 9001,
"campaignId": 1536,
"code": "ABCD1234",
"used": false,
"itemDescription": "Gift card ₡10.000",
"type": "regalia",
"valorProducto": "10000.00",
"codigoMaterial": ["MAT-001"]
}
}
}
POST
/v1/developer/gift-cards/useCanjea una gift card
válida y la marca como usada.
/v1/developer/gift-cards/useCanjea una gift card
válida y la marca como usada.{
"code": "ABCD1234",
"usedPlace": "POPS Escazú"
}
{
"success": true,
"data": {
"apiStatus": "approved",
"isApproved": true,
"data": {
"code": "ABCD1234",
"used": true,
"usedDate": "2026-05-05T10:30:00",
"usedPlace": "POPS Escazú"
}
}
}
Locations
Tiendas, bodegas y cercanía.
Las coordenadas se leen como latitude,longitude. Para cercanía, el cliente debe enviar latitud y
longitud.
GET
/v1/developer/locationsLista ubicaciones
configuradas de la tienda.
/v1/developer/locationsLista ubicaciones
configuradas de la tienda.{
"success": true,
"data": [
{
"id": 7,
"externalWarehouseId": 20,
"name": "Escazú",
"address": "San José, Escazú",
"coordinates": "9.9325,-84.0796",
"phone": "8888-8888",
"schedule": "L-S 10am-7pm",
"directionsUrl": "https://..."
}
]
}
GET
/v1/developer/locations/nearestOrdena ubicaciones
por cercanía a coordenadas del cliente.
/v1/developer/locations/nearestOrdena ubicaciones
por cercanía a coordenadas del cliente.curl "https://xapi.madebyblume.com/v1/developer/locations/nearest?latitude=9.9325&longitude=-84.0796&maxResults=5" \
-H "Authorization: Bearer $TOKEN"
Respuesta incluye distanceKm. Esto
calcula distancia directa, no tiempo de manejo.
GET
/v1/developer/locations/{externalWarehouseId}/productsProductos con stock en
una ubicación específica.
/v1/developer/locations/{externalWarehouseId}/productsProductos con stock en
una ubicación específica.{
"success": true,
"data": [
{
"externalId": 12345,
"barcode": "7440000000000",
"referenceCode": "ABC123",
"colorCode": "001",
"title": "Producto ejemplo",
"brand": "Nike",
"price": 59900,
"stockAmount": 5,
"primaryImageUrl": "https://..."
}
]
}
¿Necesita ayuda para integrar?
Genere credenciales desde el admin, pruebe con el token endpoint y escríbanos si necesita habilitar scopes o revisar un caso de uso específico. Para webhooks de integraciones específicas, instale y configure la app correspondiente desde el marketplace de Blume.