API pública para integraciones externas
Si tu plataforma de venta no es MercadoLibre ni Tienda Nube (WooCommerce, Magento, Shopify Custom App, ERP propio), esta es la forma de conectarla con Unifull. REST clásico, JSON, auth por API key. Esperamos que la integración te lleve menos de una tarde.
1. Cómo empezar
- Logueate en /account/api-keys (ruta seller).
- Tocá "Crear API key", ponele un nombre (ej: "WooCommerce producción") y elegí los scopes que necesites.
- Copiá el secret AHORA — solo aparece una vez. Si lo perdés, hay que generar uno nuevo.
- Pegale a los endpoints con el header
Authorization: Bearer <tu_secret>.
2. Scopes disponibles
Cada endpoint requiere un scope específico. Si tu API key no lo tiene, vas a recibir 401 con el motivo. Generá keys con el mínimo de permisos necesario (principle of least privilege).
orders:writeCrear y cancelar envíos.orders:readConsultar envíos por externalRef.tracking:readLeer eventos de tracking de envíos.skus:readListar el catálogo de productos del seller.skus:writeCrear o actualizar SKUs.inventory:readConsultar stock disponible por SKU.3. POST /api/v1/orders
Crear un envío en Unifull desde una orden de tu plataforma. Idempotente por externalRef — si tu integración manda 2 veces el mismo, devolvemos el shipment existente (con flag idempotent: true). Auto-crea SKUs nuevos si no existen.
Scope requerido: orders:write.
curl -X POST https://api.unifull.ar/api/v1/orders \
-H "Authorization: Bearer ufa_xxxxxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"externalRef": "WC-1234",
"destName": "Juan Pérez",
"destPhone": "+5491150001234",
"destEmail": "juan@example.com",
"destAddress": {
"street": "Av. Corrientes",
"number": "1234",
"floor": "5",
"dept": "B",
"city": "Ciudad Autónoma de Buenos Aires",
"state": "Buenos Aires",
"zipCode": "C1043"
},
"items": [
{ "sku": "ABC-001", "productName": "Remera blanca M", "quantity": 2, "unitPrice": 8500 },
{ "sku": "ABC-002", "productName": "Pantalón negro 32", "quantity": 1, "unitPrice": 14990 }
],
"totalDeclaredValue": 31990,
"carrier": "ANDREANI",
"deliveryMode": "HOME",
"packaging": "BAG_ECOMMERCE"
}'{
"id": "f4a3b1c2-...",
"internalRef": "UF-00420",
"status": "RECEIVED",
"externalRef": "WC-1234",
"createdAt": "2026-05-05T14:30:00.000Z",
"idempotent": false
}{
"id": "f4a3b1c2-...",
"internalRef": "UF-00420",
"status": "PACKED",
"externalRef": "WC-1234",
"createdAt": "2026-05-05T14:30:00.000Z",
"idempotent": true
}4. GET /api/v1/orders/:externalRef
Consultar un envío por la externalRef que vos le pasaste al crearlo. Devuelve el estado actual + tracking code + eventos del timeline.
Scope requerido: orders:read.
curl https://api.unifull.ar/api/v1/orders/WC-1234 \ -H "Authorization: Bearer ufa_xxxxxxxxxxxxxxxxxxxxxxx"
{
"id": "f4a3b1c2-...",
"internalRef": "UF-00420",
"externalRef": "WC-1234",
"status": "IN_TRANSIT",
"carrier": "ANDREANI",
"trackingCode": "20012345678",
"carrierLabelUrl": "https://andreani.com/tracking/20012345678",
"createdAt": "2026-05-05T14:30:00.000Z",
"dispatchedAt": "2026-05-06T09:15:00.000Z",
"deliveredAt": null,
"trackingEvents": [
{ "status": "RECEIVED", "description": "Recibido en Unifull", "occurredAt": "2026-05-05T14:30:00.000Z" },
{ "status": "PACKED", "description": "Empaquetado", "occurredAt": "2026-05-06T08:00:00.000Z" },
{ "status": "IN_TRANSIT", "description": "Despachado a Andreani", "occurredAt": "2026-05-06T09:15:00.000Z" }
]
}5. POST /api/v1/orders/:externalRef/cancel
Cancelar un envío. Solo posible si todavía no salió del depósito — estados RECEIVED, IN_WMS, PACKED. Si ya está en tránsito, devuelve 400.
Scope requerido: orders:write.
curl -X POST https://api.unifull.ar/api/v1/orders/WC-1234/cancel \
-H "Authorization: Bearer ufa_xxxxxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{ "reason": "Cliente canceló desde mi tienda" }'6. Errores
Todos los errores devuelven JSON shape { statusCode, message, error }. Códigos comunes:
401— API key faltante, malformada, revocada, o sin el scope necesario. Elmessagete dice exactamente qué pasó.400— Body inválido (validation errors). El message es array con la lista de campos mal.404— externalRef no existe en tu seller.429— Rate limit. Bajá el ritmo y reintentá con backoff.
7. /api/v1/skus — Catálogo
Listar / crear / actualizar SKUs del catálogo. Útil si tu plataforma es la fuente de verdad del catálogo y querés sincronizarlo con Unifull.
Scopes: skus:read / skus:write.
curl "https://api.unifull.ar/api/v1/skus?search=remera" \ -H "Authorization: Bearer ufa_xxxxxxxxxxxxxxxxxxxxxxx"
curl -X POST https://api.unifull.ar/api/v1/skus \
-H "Authorization: Bearer ufa_xxxxxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"sku": "ABC-001",
"description": "Remera blanca M",
"ean": "7791234567890",
"weightGrams": 200,
"lengthCm": 30,
"widthCm": 20,
"heightCm": 2
}'Si el SKU ya existe (mismo sellerId+sku), se actualiza en vez de duplicar. Devuelve created: false en ese caso.
8. /api/v1/inventory — Stock
Consultar stock disponible por SKU. Devuelve totalStock (lo que hay en depósito), reserved (lo que está pickeado para envíos pendientes) y available (totalStock − reserved, lo que podés vender hoy en tu tienda externa sin oversell).
Scope: inventory:read.
curl https://api.unifull.ar/api/v1/inventory \ -H "Authorization: Bearer ufa_xxxxxxxxxxxxxxxxxxxxxxx"
curl https://api.unifull.ar/api/v1/inventory/ABC-001 \ -H "Authorization: Bearer ufa_xxxxxxxxxxxxxxxxxxxxxxx"
9. Próximas mejoras
- Webhooks salientes: Unifull te avisa por POST a tu URL cuando cambia el estado de un envío. Por ahora, polling de
GET /orders/:externalRefcada 15 min funciona bien. - Bulk operations: crear múltiples orders / SKUs en una sola request.
- Rate limiting per-key: ahora todo el back tiene un límite global (100 req/min por IP). Pronto habrá límite por API key específico.
¿Necesitás algo específico que no esté? Escribinos a dev@unifull.com.ar.