# Gestión de Stocks

## Consultas de stock

La consulta de stock puedes hacerla de varias maneras:

* [Ver los stocks de un SKU determinado en todos los almacenes](https://docs.zipnova.com/envios/recursos-api/gestion-de-productos-y-skus/skus-y-stocks#detalle-de-un-sku)
* [Ver los movimientos de stock de un SKU determinado](https://docs.zipnova.com/envios/recursos-api/gestion-de-productos-y-skus/skus-y-stocks#movimientos-de-inventario)
* [Ver el stock de todos los SKUs de un almacén determinado](https://docs.zipnova.com/envios/recursos-api/almacenes-y-stock#stock-en-almacenes)

## Actualizar stocks

## Actualizar stock de un SKU en un almacén

> Actualiza el stock total y los distintos tipos de "on hold" para un SKU específico en un almacén.

```json
{"openapi":"3.0.0","info":{"title":"Zipnova Shipping API V2","version":"2.0.0"},"tags":[{"name":"Almacenes","description":"Gestión de almacenes y bodegas"}],"servers":[{"url":"https://api.zipnova.com.ar/v2","description":"v2 API - Argentina (AR)"},{"url":"https://api.zipnova.cl/v2","description":"v2 API - Chile (CL)"},{"url":"https://api.zipnova.com.mx/v2","description":"v2 API - México (MX)"}],"security":[{"basicAuth":[]},{"bearerAuth":[]}],"components":{"securitySchemes":{"basicAuth":{"type":"http","description":"Autenticación básica HTTP utilizando token como nombre de usuario y secret como contraseña","scheme":"basic"},"bearerAuth":{"type":"http","description":"Token de autenticación Bearer OAuth para API V2","bearerFormat":"OAuth","scheme":"bearer"}},"schemas":{"Stock":{"title":"Stock","description":"Representa el stock de un SKU en un depósito específico, incluyendo cantidades disponibles, asignadas y en espera.","properties":{"sku":{"$ref":"#/components/schemas/SkuBasic"},"warehouse":{"description":"Código del depósito","type":"string"},"qty_available":{"description":"Cantidad disponible para asignar a envíos","type":"integer"},"qty_allocated":{"description":"Cantidad asignada a envíos pendientes","type":"integer"},"qty_total":{"description":"Cantidad total en el depósito (disponible + asignada + en espera)","type":"integer"},"qty_warehouse":{"description":"Cantidad física presente en el depósito","type":"integer"},"qty_on_hold_broken":{"description":"Cantidad retenida por daño","type":"integer"},"qty_on_hold_expiration":{"description":"Cantidad retenida por vencimiento próximo","type":"integer"},"qty_on_hold_for_review":{"description":"Cantidad retenida pendiente de revisión de calidad","type":"integer"},"updated_at":{"description":"Fecha de última actualización del stock","type":"string","format":"date-time"}},"type":"object"},"SkuBasic":{"title":"SkuBasic","description":"Información básica de un SKU","properties":{"sku":{"description":"Código SKU del producto","type":"string"},"internal_sku":{"description":"Código interno del SKU","type":"string"},"account_id":{"description":"ID de la cuenta propietaria del SKU","type":"integer"},"management_type":{"description":"Tipo de gestión del SKU en el almacén","type":"string"}},"type":"object"}}},"paths":{"/warehouses/{warehouse}/skus/{sku}/stock":{"put":{"tags":["Almacenes"],"summary":"Actualizar stock de un SKU en un almacén","description":"Actualiza el stock total y los distintos tipos de \"on hold\" para un SKU específico en un almacén.","operationId":"016e0c37978ffc5f076b4a4b3bd57597","parameters":[{"name":"warehouse","in":"path","description":"Código del almacén","required":true,"schema":{"type":"string"}},{"name":"sku","in":"path","description":"ID interno o código del SKU","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"qty_total":{"description":"Cantidad total de stock","type":"integer"},"qty_on_hold_broken":{"description":"Cantidad en hold por rotura","type":"integer"},"qty_on_hold_expiration":{"description":"Cantidad en hold por vencimiento","type":"integer"},"qty_on_hold_for_review":{"description":"Cantidad en hold para revisión","type":"integer"},"comments":{"description":"Comentario sobre el movimiento","type":"string"}},"type":"object"}}}},"responses":{"200":{"description":"Stock actualizado exitosamente","content":{"application/json":{"schema":{"properties":{"message":{"description":"Confirmación de la operación","type":"string"},"stock":{"$ref":"#/components/schemas/Stock"}},"type":"object"}}}},"400":{"description":"Datos inválidos o error al actualizar stock"},"403":{"description":"Sin permiso para actualizar stock en este almacén"},"404":{"description":"Almacén o SKU no encontrado"},"500":{"description":"Error interno del servidor"}}}}}}
```

### Crear un movimiento de stock

## Registrar movimiento de inventario

> Registra un movimiento de inventario (entrada, salida o hold) para un SKU en un almacén.\
> \
> El campo \`quantity\` siempre debe ser positivo. El sistema determina el signo automáticamente según el prefijo del \`type\`:\
> \- Tipos \`in\_\*\`: se registran como entrada (suma stock)\
> \- Tipos \`out\_\*\`: se registran como salida (resta stock)\
> \- Tipos \`hold\_\*\`: colocan unidades en espera (no modifica qty\_total)\
> \- Tipos \`unhold\_\*\`: liberan unidades de espera\
> \
> El campo \`external\_id\` garantiza idempotencia: si se envía el mismo \`external\_id\` para el mismo SKU y almacén, el movimiento no se duplica.

```json
{"openapi":"3.0.0","info":{"title":"Zipnova Shipping API V2","version":"2.0.0"},"tags":[{"name":"Almacenes","description":"Gestión de almacenes y bodegas"}],"servers":[{"url":"https://api.zipnova.com.ar/v2","description":"v2 API - Argentina (AR)"},{"url":"https://api.zipnova.cl/v2","description":"v2 API - Chile (CL)"},{"url":"https://api.zipnova.com.mx/v2","description":"v2 API - México (MX)"}],"security":[{"basicAuth":[]},{"bearerAuth":[]}],"components":{"securitySchemes":{"basicAuth":{"type":"http","description":"Autenticación básica HTTP utilizando token como nombre de usuario y secret como contraseña","scheme":"basic"},"bearerAuth":{"type":"http","description":"Token de autenticación Bearer OAuth para API V2","bearerFormat":"OAuth","scheme":"bearer"}},"schemas":{"SkuMovementResource":{"title":"Movimiento de SKU","description":"Representa un movimiento de inventario de un SKU en un depósito (entrada, salida, ajuste, etc.).","properties":{"id":{"description":"ID del movimiento","type":"integer"},"created_at":{"description":"Fecha y hora en que se registró el movimiento","type":"string","format":"date-time"},"sku":{"description":"Identificación del SKU afectado","properties":{"sku":{"description":"Código del SKU","type":"string"},"internal_sku":{"description":"SKU interno","type":"string","nullable":true},"account_id":{"description":"ID de la cuenta propietaria","type":"integer"}},"type":"object"},"warehouse":{"description":"Código del depósito donde ocurrió el movimiento","type":"string","nullable":true},"movement":{"description":"Detalle del movimiento de stock","properties":{"qty_changed":{"description":"Cantidad que cambió (positivo para entradas, negativo para salidas)","type":"integer"},"type":{"description":"Tipo de movimiento: IN (entrada) o OUT (salida)","type":"string"},"code":{"description":"Código del motivo del movimiento","type":"string"},"reason":{"description":"Descripción del motivo del movimiento","type":"string"},"comments":{"description":"Comentarios adicionales sobre el movimiento","type":"string","nullable":true}},"type":"object"}},"type":"object"}}},"paths":{"/warehouses/{warehouse}/movements":{"post":{"tags":["Almacenes"],"summary":"Registrar movimiento de inventario","description":"Registra un movimiento de inventario (entrada, salida o hold) para un SKU en un almacén.\n\nEl campo `quantity` siempre debe ser positivo. El sistema determina el signo automáticamente según el prefijo del `type`:\n- Tipos `in_*`: se registran como entrada (suma stock)\n- Tipos `out_*`: se registran como salida (resta stock)\n- Tipos `hold_*`: colocan unidades en espera (no modifica qty_total)\n- Tipos `unhold_*`: liberan unidades de espera\n\nEl campo `external_id` garantiza idempotencia: si se envía el mismo `external_id` para el mismo SKU y almacén, el movimiento no se duplica.","operationId":"ba2b661c6020071279cc094f83786ade","parameters":[{"name":"warehouse","in":"path","description":"Código del almacén","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"required":["quantity","external_id"],"properties":{"type":{"description":"Código del motivo del movimiento. Determina si es entrada, salida o hold.","type":"string","enum":["in_received","in_return","in_rejected","in_canceled_out","in_transfer","out_shipped","out_unstocked","out_expired","out_lost","out_transfer","out_broken","out_confiscated","out_review","hold_for_review","hold_broken","hold_expiration","unhold_for_review","unhold_broken","unhold_expiration","adjustment"]},"sku":{"description":"Código `sku` del producto. Requerido si no se envía `internal_sku`.","type":"string"},"internal_sku":{"description":"Código `internal_sku` del producto. Requerido si no se envía `sku`.","type":"string"},"quantity":{"description":"Cantidad del movimiento. Siempre enviar un valor positivo; el sistema aplica el signo según el tipo.","type":"integer"},"external_id":{"description":"Identificador externo del movimiento. Garantiza idempotencia: si ya existe un movimiento con este ID para el mismo SKU y almacén, no se duplica.","type":"string"},"comments":{"description":"Comentarios opcionales sobre el movimiento","type":"string"},"relation_type":{"description":"Tipo de entidad relacionada con este movimiento","type":"string","enum":["fulfillment_order_id","fulfillment_warehouse_order_id"]},"relation_id":{"description":"ID de la entidad relacionada (corresponde al tipo indicado en `relation_type`)","type":"string"}},"type":"object"}}}},"responses":{"201":{"description":"Movimiento registrado exitosamente","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SkuMovementResource"}}}},"400":{"description":"Datos inválidos o el movimiento no pudo registrarse (ver errores en el body)"},"403":{"description":"Sin permiso para registrar movimientos en este almacén o almacén deshabilitado"},"404":{"description":"Almacén o SKU no encontrado"},"422":{"description":"Movimiento ignorado (no aplica para esta combinación de cuenta/tipo)"}}}}}}
```

## Listar tipos de movimiento

> Obtiene una lista de todos los tipos de movimiento de inventario disponibles.

```json
{"openapi":"3.0.0","info":{"title":"Zipnova Shipping API V2","version":"2.0.0"},"tags":[{"name":"Inventario","description":"Gestión de inventario y stock"}],"servers":[{"url":"https://api.zipnova.com.ar/v2","description":"v2 API - Argentina (AR)"},{"url":"https://api.zipnova.cl/v2","description":"v2 API - Chile (CL)"},{"url":"https://api.zipnova.com.mx/v2","description":"v2 API - México (MX)"}],"security":[{"basicAuth":[]},{"bearerAuth":[]}],"components":{"securitySchemes":{"basicAuth":{"type":"http","description":"Autenticación básica HTTP utilizando token como nombre de usuario y secret como contraseña","scheme":"basic"},"bearerAuth":{"type":"http","description":"Token de autenticación Bearer OAuth para API V2","bearerFormat":"OAuth","scheme":"bearer"}},"schemas":{"MovementTypeResource":{"title":"Tipo de Movimiento","description":"Motivo o tipo de movimiento de inventario. Usar el campo code al referenciar un tipo de movimiento en otras operaciones.","properties":{"code":{"description":"Código del tipo de movimiento","type":"string"},"name":{"description":"Nombre descriptivo del tipo de movimiento","type":"string"}},"type":"object"}}},"paths":{"/inventory/movement_types":{"get":{"tags":["Inventario"],"summary":"Listar tipos de movimiento","description":"Obtiene una lista de todos los tipos de movimiento de inventario disponibles.","operationId":"bca9efbd02e50611b3927ef15a67ca49","responses":{"200":{"description":"Lista de tipos de movimiento","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/MovementTypeResource"}}}}},"401":{"description":"No autenticado"},"403":{"description":"Prohibido"}}}}}}
```
