Blume Developer API
Integre Blume con apps externas, canales B2B, ERPs, inventario, clientes, órdenes 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 órdenes, 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 tiendas/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 órdenes y consultar detalle con cliente, dirección, totales e items. | /orders |
orders:write |
Crear órdenes, actualizar estados permitidos y actualizar líneas de una orden. | /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 gift cards sin consumirlas. | /gift-cards/verify |
giftcards:write |
Verificar y canjear gift cards. | /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 una orden. |
order.paid |
Cuando una orden queda pagada. |
order.cancelled |
Cuando una orden 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 una orden
creada.
order.createdEjemplo de payload para una orden
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 a la tienda. |
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, tienda 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 órdenes con
filtros básicos./v1/developer/orders/{orderId}Detalle de
orden con cliente, dirección, totales e items./v1/developer/ordersCrea una orden
retail./v1/developer/orders/{orderId}/statusActualiza
estados permitidos./v1/developer/orders/items/updateReemplaza
líneas y totales de una orden./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 gift card./v1/developer/gift-cards/useCanjea una
gift card 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 tienda 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 la tienda del token.
/v1/developer/carts/summaryResumen de carritos
abandonados y recuperación para la tienda 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
Órdenes, detalle y estados.
La creación de órdenes 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 órdenes con filtros
básicos.
/v1/developer/ordersLista órdenes 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 una orden retail para la
tienda asociada al token.
/v1/developer/ordersCrea una orden 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 una orden y actualiza subtotal, descuento y total.
/v1/developer/orders/items/updateReemplaza las
líneas de una orden 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
}
}
Gift cards
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.