Saltar al contenido principal

API de e-commerce

Gestiona tu catálogo de productos, rastrea pedidos, supervisa la actividad de los carritos y analiza segmentos RFM de clientes.

Todos los endpoints de esta página son relativos a la URL base: https://api-eu1.joryio.com. Consulta el resumen de la API.

Convención de nombres de ID

Joryio usa una convención clara para los identificadores:

Tus ID (úsalos al crear o rastrear datos)

CampoDescripciónEjemplo
productIdTu identificador de producto (SKU o ID de producto de tu plataforma de e-commerce)."SKU-12345"
orderIdTu identificador de pedido (número de pedido de tu plataforma)."ORD-2024-001"
userIdTu identificador de usuario."user-123"

ID de Joryio (devueltos en las respuestas API)

CampoDescripciónCuándo usarlo
idID interno de Joryio para productos/pedidos.Se devuelve en respuestas API; úsalo para actualizar/eliminar.
joryioUserIdID de usuario interno de Joryio (el id de 24 caracteres hexadecimales devuelto por la API de usuarios).Alternativa a userId cuando quieras referenciar mediante el ID de Joryio.

Identificación flexible de usuario

Al crear pedidos o rastrear eventos, puedes identificar usuarios mediante uno de estos campos:

  • userId: tu identificador de usuario (el más habitual).
  • joryioUserId: ID de usuario interno de Joryio.
// Usando tu ID de usuario (recomendado)
{ "orderId": "ORD-001", "userId": "user-123", ... }

// Usando el ID de usuario interno de Joryio
{ "orderId": "ORD-001", "joryioUserId": "66a1f2c3d4e5f6a7b8c9d0e1", ... }

Autenticación

Todas las solicitudes requieren autenticación JWT:

Authorization: Bearer your_jwt_token
Content-Type: application/json
X-Workspace-Id: your_workspace_id

Catálogo de productos

Crear un producto

Crea un producto nuevo en tu catálogo.

POST /catalog/products

Cuerpo de la solicitud:

CampoTipoObligatorioDescripción
productIdcadenaTu identificador de producto único (SKU o ID de producto).
namecadenaNombre del producto.
pricenúmeroPrecio del producto.
descriptioncadenaNoDescripción del producto.
compareAtPricenúmeroNoPrecio original (para descuentos).
currencycadenaNoCódigo de moneda (predeterminado: USD).
categoriescadena[]NoCategorías de producto.
tagscadena[]NoEtiquetas de producto.
brandcadenaNoNombre de la marca.
imageUrlcadenaNoURL de imagen principal de producto.
urlcadenaNoURL de página de producto.
inStockbooleanoNoDisponibilidad de stock (predeterminado: true).
skucadenaNoUnidad de mantenimiento de stock.
variantsobjeto[]NoVariantes de producto.
customFieldsobjetoNoAtributos personalizados.

Solicitud de ejemplo:

curl -X POST https://api-eu1.joryio.com/catalog/products \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"productId": "SKU-12345",
"name": "Classic Blue T-Shirt",
"price": 29.99,
"compareAtPrice": 39.99,
"currency": "USD",
"categories": ["Clothing", "T-Shirts"],
"tags": ["sale", "bestseller"],
"brand": "Acme Apparel",
"imageUrl": "https://example.com/images/blue-tshirt.jpg",
"url": "https://example.com/products/blue-tshirt",
"inStock": true,
"sku": "BTS-001-BL",
"variants": [
{
"id": "var-s",
"name": "Small",
"sku": "BTS-001-BL-S",
"price": 29.99,
"inStock": true,
"options": { "size": "S", "color": "Blue" }
},
{
"id": "var-m",
"name": "Medium",
"sku": "BTS-001-BL-M",
"price": 29.99,
"inStock": true,
"options": { "size": "M", "color": "Blue" }
}
]
}'

Respuesta:

{
"id": "prod_abc123",
"productId": "SKU-12345",
"name": "Classic Blue T-Shirt",
"price": 29.99,
"createdAt": "2024-01-20T10:00:00.000Z"
}

Upsert masivo de productos (cuerpo de matriz)

No hay un endpoint masivo independiente: POST /catalog/products acepta un objeto de producto único o una matriz JSON de objetos de producto, sin objeto envoltorio. El formato de matriz crea o actualiza hasta 500 productos en una solicitud, mediante upsert por productId.

POST /catalog/products

Cuerpo de la solicitud:

Una matriz JSON de hasta 500 elementos; una matriz vacía o con más de 500 devuelve 400. Cada elemento sigue el mismo formato que el objeto único, incluido el campo opcional source por producto.

Cada elemento recibe una validación completa. Un elemento no válido se informa en failed mediante su índice de matriz, nunca se acepta silenciosamente, y los elementos válidos restantes reciben upsert de todos modos.

[
{ "productId": "SKU-001", "name": "Product 1", "price": 19.99 },
{ "productId": "SKU-002", "name": "Product 2", "price": 29.99, "source": "shopify" }
]

Respuesta:

A diferencia del formato de objeto, que devuelve el producto creado, el formato de matriz devuelve un resumen agregado:

{
"processed": 2,
"upserted": 2,
"failed": []
}
CampoDescripción
processedNúmero de elementos recibidos en la matriz de solicitud.
upsertedProductos creados o actualizados realmente.
failedErrores por elemento: index (posición en la matriz de solicitud), productId / sku (cuando existen en el elemento) y reason.

Listar productos

Consulta productos con filtrado y paginación.

GET /catalog/products

Parámetros de consulta:

ParámetroTipoDescripción
searchcadenaBusca por nombre, descripción o SKU.
categoriescadena[]Filtra por categorías.
tagscadena[]Filtra por etiquetas.
brandcadenaFiltra por marca.
inStockbooleanoFiltra por estado de stock.
minPricenúmeroPrecio mínimo.
maxPricenúmeroPrecio máximo.
limitnúmeroResultados por página (predeterminado: 50).
offsetnúmeroDesplazamiento de paginación.
sortBycadenaCampo de orden: name, price, createdAt, updatedAt.
sortOrdercadenaasc o desc.

Ejemplo:

curl "https://api-eu1.joryio.com/catalog/products?categories=T-Shirts&inStock=true&limit=20" \
-H "Authorization: Bearer $TOKEN"

Obtener categorías

Lista todas las categorías de producto.

GET /catalog/categories

Obtener marcas

Lista todas las marcas de producto.

GET /catalog/brands

Pedidos

Crear un pedido

Rastrea un pedido nuevo.

POST /orders

Cuerpo de la solicitud:

CampoTipoObligatorioDescripción
orderIdcadenaTu ID de pedido (número de pedido de tu plataforma).
userIdcadenaUno de los dosID de usuario de tu cliente.
joryioUserIdcadenaUno de los dosID de usuario interno de Joryio (alternativa a userId).
totalnúmeroTotal del pedido.
itemsobjeto[]Líneas de pedido.
statuscadenaNoEstado del pedido (predeterminado: pending).
currencycadenaNoCódigo de moneda.
subtotalnúmeroNoSubtotal antes de descuentos.
discountnúmeroNoImporte del descuento.
shippingnúmeroNoCoste de envío.
taxnúmeroNoImporte de impuestos.
totalRefundednúmeroNoImporte reembolsado hasta ahora, en la moneda del pedido (predeterminado 0). Para un reembolso parcial, envía el importe parcial con status: partiallyRefunded; para un reembolso total, define total con status: refunded. Los reembolsos se deducen de los ingresos atribuidos.
couponCodecadenaNoCupón aplicado.
shippingAddressobjetoNoDirección de envío.
campaignIdcadenaNoCampaña de atribución.
canvasIdcadenaNoCanvas de atribución.
sourcecadenaNoFuente del pedido (email, sms, direct).
utmSourcecadenaNoFuente UTM.
utmMediumcadenaNoMedio UTM.
utmCampaigncadenaNoCampaña UTM.
Identificación de usuario

Debes proporcionar userId o joryioUserId. Usa userId con tus propios identificadores de usuario (lo más habitual). Usa joryioUserId si dispones del ID de usuario interno de Joryio (el id de 24 caracteres hexadecimales devuelto por la API de usuarios).

Estructura de línea de pedido:

{
"productId": "prod_abc123",
"name": "Blue T-Shirt",
"sku": "BTS-001",
"quantity": 2,
"price": 29.99,
"total": 59.98,
"imageUrl": "https://example.com/image.jpg"
}

Solicitud de ejemplo:

curl -X POST https://api-eu1.joryio.com/orders \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"orderId": "ORD-2024-001",
"userId": "user-123",
"total": 89.97,
"subtotal": 99.97,
"discount": 10.00,
"shipping": 5.99,
"tax": 4.99,
"currency": "USD",
"couponCode": "SAVE10",
"items": [
{
"productId": "prod_abc123",
"name": "Blue T-Shirt",
"quantity": 2,
"price": 29.99,
"total": 59.98
},
{
"productId": "prod_def456",
"name": "Black Jeans",
"quantity": 1,
"price": 49.99,
"total": 49.99
}
],
"source": "email",
"campaignId": "camp_xyz789"
}'

Completar un pedido

Marca un pedido como enviado.

POST /orders/:id/fulfill

Cuerpo de la solicitud:

{
"trackingNumber": "1Z999AA10123456784",
"carrier": "UPS"
}

Cancelar un pedido

Cancela un pedido.

POST /orders/:id/cancel

Cuerpo de la solicitud:

{
"reason": "Customer requested cancellation"
}

Reembolsar un pedido

Procesa un reembolso.

POST /orders/:id/refund

Cuerpo de la solicitud:

{
"refundAmount": 29.99,
"reason": "Product defective",
"partial": true
}

Estadísticas de pedidos

Obtiene estadísticas de pedidos para un intervalo de fechas.

GET /orders/stats?startDate=2024-01-01&endDate=2024-01-31

Respuesta:

{
"totalOrders": 156,
"totalRevenue": 12450.50,
"averageOrderValue": 79.81,
"ordersByStatus": {
"pending": 5,
"processing": 12,
"shipped": 45,
"delivered": 90,
"cancelled": 4
}
}

Rastreo de carritos

Actualizar un carrito

Rastrea o actualiza el carrito de un usuario.

PUT /carts

Cuerpo de la solicitud:

{
"userId": "user_123",
"items": [
{
"productId": "prod_abc123",
"name": "Blue T-Shirt",
"price": 29.99,
"quantity": 2,
"total": 59.98,
"imageUrl": "https://example.com/image.jpg"
}
],
"value": 59.98,
"currency": "USD",
"checkoutUrl": "https://store.example.com/checkout?cart=abc123"
}

Añadir al carrito

Añade un artículo al carrito de un usuario.

POST /carts/add

Cuerpo de la solicitud:

{
"userId": "user_123",
"item": {
"productId": "prod_abc123",
"name": "Blue T-Shirt",
"price": 29.99,
"quantity": 1,
"total": 29.99
}
}

Obtener carritos abandonados

Lista carritos abandonados para campañas de recuperación.

GET /carts/abandoned

Parámetros de consulta:

ParámetroTipoDescripción
minValuenúmeroValor mínimo del carrito.
abandonedMinutesAgonúmeroMáximo de minutos desde el abandono.
limitnúmeroResultados por página.
offsetnúmeroDesplazamiento de paginación.

Respuesta:

{
"data": [
{
"id": "cart_123",
"userId": "user_456",
"items": [...],
"value": 149.99,
"abandonedAt": "2024-01-20T15:30:00.000Z",
"checkoutUrl": "https://store.example.com/checkout?cart=abc"
}
],
"total": 42,
"hasMore": true
}

Estadísticas de carritos

Obtiene estadísticas de carritos y abandonos.

GET /carts/stats

Respuesta:

{
"totalCarts": 1250,
"abandonedCarts": 312,
"recoveredCarts": 87,
"totalAbandonedValue": 45670.50,
"recoveryRate": 27.88
}

Análisis RFM

El análisis RFM (recencia, frecuencia y valor monetario) segmenta a los clientes según su comportamiento de compra.

Obtener datos RFM de un usuario

Obtiene las puntuaciones y el segmento RFM de un usuario concreto.

GET /rfm/user/:userId

Respuesta:

{
"totalOrders": 12,
"totalSpent": 849.50,
"averageOrderValue": 70.79,
"firstOrderDate": "2023-06-15T10:00:00.000Z",
"lastOrderDate": "2024-01-18T14:30:00.000Z",
"daysSinceLastOrder": 2,
"hasActiveCart": false,
"rfmRecency": 5,
"rfmFrequency": 4,
"rfmMonetary": 4,
"rfmScore": "544",
"rfmSegment": "champions"
}

Obtener distribución RFM

Obtiene la distribución de clientes entre los segmentos RFM.

GET /rfm/distribution

Respuesta:

{
"champions": { "count": 150, "totalValue": 125000 },
"loyal": { "count": 320, "totalValue": 89000 },
"potential_loyalists": { "count": 180, "totalValue": 32000 },
"new_customers": { "count": 450, "totalValue": 28000 },
"at_risk": { "count": 95, "totalValue": 42000 },
"lost": { "count": 280, "totalValue": 15000 }
}

Segmentos RFM

SegmentoDescripciónPuntuaciones RFM típicas
CampeonesMejores clientes; compran a menudo y gastan más.555, 554, 545
LealesClientes constantes.444, 443, 434
Leales potencialesRecientes, con frecuencia media.433, 343, 333
Clientes nuevosAcaban de hacer su primera compra.511, 512, 411
PrometedoresRecientes, pero con frecuencia baja.422, 322, 312
Necesitan atenciónInteracción media en descenso.332, 322, 233
A punto de dormirsePor debajo de la media, en riesgo.211, 212, 221
En riesgoFueron leales, pero no han comprado recientemente.144, 143, 244
No se pueden perderFueron los mejores clientes y ahora están inactivos.155, 154, 255
HibernandoInteracción baja, inactivos desde hace tiempo.122, 121, 112
PerdidosPuntuaciones más bajas, probablemente abandonaron.111

Webhooks

Los eventos de e-commerce emiten webhooks que pueden activar flujos de Canvas:

EventoDescripción
ecommerce.order.createdSe realizó un pedido nuevo.
ecommerce.order.fulfilledPedido enviado.
ecommerce.order.cancelledPedido cancelado.
ecommerce.order.refundedPedido reembolsado.
ecommerce.order.status_changedCambió el estado del pedido.
ecommerce.cart.abandonedCarrito marcado como abandonado.
ecommerce.cart.recoveredCarrito abandonado recuperado.
ecommerce.cart.updatedCambió el contenido del carrito.

Consultar por tus ID

Obtener un producto por tu ID de producto

Recupera un producto mediante tu identificador de producto.

GET /catalog/products/by-product-id/:productId

Ejemplo:

curl "https://api-eu1.joryio.com/catalog/products/by-product-id/SKU-12345" \
-H "Authorization: Bearer $TOKEN"

Obtener un pedido por tu ID de pedido

Recupera un pedido mediante tu identificador de pedido.

GET /orders/by-order-id/:orderId

Ejemplo:

curl "https://api-eu1.joryio.com/orders/by-order-id/ORD-2024-001" \
-H "Authorization: Bearer $TOKEN"

Respuestas de error

{
"statusCode": 404,
"message": "Product SKU-12345 not found",
"error": "Not Found"
}
Código de estadoDescripción
400Cuerpo de solicitud no válido.
401Se requiere autenticación.
403Permisos insuficientes.
404Recurso no encontrado.
409Conflicto (ID externo duplicado).
500Error interno del servidor.