Sincronizar tu ERP

Sincronizar tu ERP

El flujo de un día: mapear el catálogo, escribir stock y precios, leer pedidos y seguir los cambios.

Mapear tu catálogo

En cada ítem de escritura, direccionás la variante con exactamente una de estas referencias:

  • sku — lo más común; es tu código en el ERP.
  • barcode — el código de barras (EAN).
  • variantId — el id de Mandadito (lo leés de GET /products).

Mandar dos referencias a la vez es 422 VALIDATION_ERROR. Si un SKU está repetido en la tienda, es 409 SKU_AMBIGUOUS: ahí direccioná por barcode o variantId. Si no coincide ninguna, es 404 VARIANT_NOT_FOUND.

Pronto vas a poder guardar un externalId estable (el id de tu ERP) sobre cada producto y variante, para mapear una vez y después sincronizar por esa clave.

Stock: set contra adjust

Hay dos formas de escribir stock, las dos en lote (hasta 50 ítems) y las dos por ítem:

  • set fija el stock absoluto. Es lo que usás en una sincronización nocturna: "este SKU tiene 42".
  • adjust registra un movimiento (delta). Es lo que usás ante una venta o una entrada en tu sistema: "restá 3".
curl -X POST https://api.mandaditoapp.com/partner/v1/inventory/levels/set \
  -H "Authorization: Bearer mdt_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "items": [
      { "sku": "SUP-000123", "quantity": 42 },
      { "sku": "NO-EXISTE",  "quantity": 5 }
    ],
    "reason": "recuento"
  }'

La respuesta trae una fila por ítem, en orden. La escritura nunca es todo o nada: las filas buenas se aplican y la fallada vuelve con su código.

{
  "results": [
    { "index": 0, "ok": true,  "status": 200, "quantity": 42 },
    { "index": 1, "ok": false, "status": 404, "code": "VARIANT_NOT_FOUND", "message": "No variant matches this reference." }
  ]
}

Cada cambio escribe una fila en el kardex de la tienda (fuente api, con el nombre de tu clave como actor), así el comerciante ve de dónde salió.

Evitar pisar una venta

En un set podés mandar expectedQuantity: escribe solo si el nivel todavía vale eso. Si cambió en el medio, es 409 STOCK_CHANGED y quantity te devuelve el nivel actual para que releas y reintentes.

{ "items": [ { "sku": "SUP-000123", "quantity": 42, "expectedQuantity": 45 } ] }

Con adjust, quitar más de lo que hay es 409 INSUFFICIENT_STOCK (nunca se recorta a cero). Y una variante que no controla stock es 409 VARIANT_NOT_TRACKED, salvo que mandes enableTracking: true, que lo activa en la misma escritura.

Precios

El precio de venta, el precio tachado y el costo se escriben juntos, también en lote:

curl -X POST https://api.mandaditoapp.com/partner/v1/variants/prices \
  -H "Authorization: Bearer mdt_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "items": [
      { "sku": "SUP-000123", "price": 1250.50, "compareAtPrice": 1500, "cost": 820 }
    ]
  }'

Los montos son en pesos, hasta 2 decimales. compareAtPrice no puede ser menor a price (mandá 0 para quitarlo). Para las listas de precios B2B, cada lista tiene sus sobreescrituras:

PUT https://api.mandaditoapp.com/partner/v1/price-lists/66c1.../items
{ "items": [ { "sku": "SUP-000123", "price": 1100 } ] }

Idempotencia

Toda escritura acepta el header opcional Idempotency-Key (una clave única por intento, válida 24 h). Reintentar con la misma clave nunca duplica la escritura, aunque se corte la red:

  • Misma clave + mismo cuerpo → te devuelve la respuesta original con Idempotency-Replayed: true, sin volver a escribir.
  • Misma clave + otro cuerpo → 422 IDEMPOTENCY_KEY_REUSED. Usá una clave nueva para un pedido nuevo.
  • Mientras el primer intento sigue en curso → 409 IDEMPOTENCY_IN_PROGRESS.
  • Un error 5xx libera la clave para que puedas reintentar.
-H "Idempotency-Key: erp-sync-2026-10-20-0001"

Leer pedidos para facturar

Con orders:read leés los pedidos con sus ítems (SKU, cantidad, precio unitario, totales), el medio de pago y el método de entrega. Lo importante para un ERP: si nosotros ya emitimos la factura, el pedido trae un resumen del comprobante (tipo, número, CAE), para que no lo dupliques.

curl "https://api.mandaditoapp.com/partner/v1/orders?financialStatus=paid&updatedSince=2026-10-20T00:00:00Z" \
  -H "Authorization: Bearer mdt_live_..."

El feed de cambios

Para sincronizar solo lo que se movió, en vez de releer todo:

  • GET /inventory/movements?since= — el kardex como feed: cada movimiento con source, delta, quantityBefore, quantityAfter y, si vino de un pedido, su nombre.
  • GET /products?updatedSince= y GET /orders?updatedSince= — lo que cambió desde tu última corrida.

Guardá la hora de cada corrida y volvé a pedir desde ahí. Más adelante, los webhooks van a avisarte en el momento (stock, precios, pedidos) para que dejes de hacer polling.

¿Dudas con los permisos o un código de error? Mirá Autenticación. La referencia completa, campo por campo, está en api.mandaditoapp.com/docs.