> ## Documentation Index
> Fetch the complete documentation index at: https://muveya.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Historial de custodia

> Sigue las cajas, los movimientos de existencias y los registros de entrega, recepción y cierre de un pedido, y lee el mismo historial desde la API.

El detalle de custodia cuenta toda la historia de la entrega de un pedido: qué cajas se reservaron, quién las tomó y las despachó, quién confirmó la entrega, qué aceptó o disputó el destino y quién cerró el pedido. Úsalo para seguir una entrega en el día a día y para responder preguntas de auditoría o disputas más adelante.

## Quién puede verlo

* Permiso `fulfillment.read` (**Ver abastecimiento**).
* La sede del pedido en tu **Acceso a sedes**.

Sin el permiso, la pantalla dice "No puedes ver entregas. Pide el permiso al administrador de tu clínica." Un pedido fuera de tus sedes, o que todavía no tiene registro de custodia, responde "Esta entrega no existe o no puedes verla."

## Dónde

* En **Entregas**, sección **Por cerrar** o **Problemas de entrega**, selecciona el número del pedido.
* En la página del pedido, **Seguir la entrega** (se muestra a quienes tienen algún permiso de custodia). Consulta [Crear y seguir pedidos](/docs/es/orders/create-and-track).
* Después de confirmar una recepción, el enlace debajo del mensaje de confirmación.
* En la pantalla de preparación de un pedido que ya no se está preparando, el enlace **Seguimiento del pedido #1042**.
* Ruta directa: `console.muveya.com/fulfillment/:orderId`.

## Qué muestra la pantalla

La pantalla se titula **Seguimiento del pedido #1042**, con **Volver a entregas** para regresar a la lista.

### Datos y siguiente paso

| Dato | Qué muestra |
| - | - |
| **Estado** | El estado de custodia, por ejemplo **Despachado**. Consulta la [tabla de estados](/docs/es/deliveries/overview#el-ciclo-de-custodia). |
| **Clínica** | La sede del pedido. |
| **Entregar en** | La bodega de destino. |

Debajo de los datos, la pantalla ofrece el siguiente paso cuando te toca darlo:

| Estado | Enlace o panel | Se muestra a quien tiene |
| - | - | - |
| **Existencias reservadas**, **En preparación** | **Preparar el pedido** | `fulfillment.pick` |
| **Despachado** | **Confirmar la entrega** | `delivery.confirm` |
| **Entregado** | **Recibir el pedido** | `receipt.confirm` |
| **Recibido**, **Recibido en parte** | "Todo se recibió o se devolvió. Cierra el pedido para terminarlo." con **Cerrar pedido** | `fulfillment.close` |
| **Problema de entrega** | "La resolución está pendiente con el dueño de la clínica. Por ahora no se puede hacer nada más aquí." | Todos los que pueden ver la página |

Para cerrar, consulta [Cerrar el pedido](/docs/es/deliveries/delivery-and-receipt#cerrar-el-pedido).

### Cajas

**Cajas** lista cada caja asignada al pedido. En un teléfono, cada caja se muestra como una tarjeta con etiquetas.

| Columna | Qué muestra |
| - | - |
| **Código de caja** | El código impreso en la etiqueta. |
| **Estado de la caja** | El estado actual de la caja (consulta abajo). |
| **Insumo** | El nombre y el SKU del insumo. |
| **Cantidad** | La cantidad que la caja lleva para este pedido. |
| **Lote** | El número de lote, cuando la caja lo tiene. |
| **Vence** | La fecha de vencimiento, cuando la caja la tiene. |

| Estado de la caja | Qué significa en la custodia |
| - | - |
| **Activa** | Reservada o tomada y todavía en la bodega de origen, o aceptada en el destino, o devuelta sin cuarentena. |
| **En tránsito** | Despachada y todavía no recibida ni devuelta. |
| **En cuarentena** | Devuelta por una disputa con cuarentena, o puesta en cuarentena por otro motivo (por ejemplo un [retiro de lote](/docs/es/inventory/lot-recall)). |
| **Vencida**, **Agotada**, **Dada de baja** | La caja cambió después, fuera de esta entrega. |

Cuando una caja se separó al preparar, la lista muestra el contenedor nuevo, no la caja original. Si no hay cajas asignadas, la pantalla dice "No hay cajas asignadas a este pedido."

### Historial

**Historial** lista lo que pasó, una entrada por evento, cada una con la persona y la fecha y hora en el formato de tu navegador. Las personas aparecen con su nombre en el equipo; quien tiene la sesión abierta aparece como **Tú**, las acciones que muveya hizo por su cuenta como **Muveya (automático)**, y quienes salieron del equipo como **Ex integrante del equipo**.

Primero van los **movimientos de existencias**, del más antiguo al más reciente. Cada uno se lee "movimiento · código de caja · cambio de cantidad", por ejemplo "Despachado · BX-000123 · -10". Los movimientos que no cambian la cantidad disponible omiten el número, por ejemplo "Tomado para el pedido · BX-000123".

| Movimiento | Código | Cuándo aparece | Cambio de cantidad |
| - | - | - | - |
| **Reservado** | `reserve` | La reserva automática, o una reserva que pasó a un contenedor separado. | Ninguno (crece la cantidad reservada de la caja) |
| **Liberado** | `release` | Una reserva que salió de la caja original durante una separación. | Ninguno |
| **Separación (salida)** | `split_out` | La cantidad del pedido salió de la caja original. | Negativo |
| **Separación (entrada)** | `split_in` | La cantidad del pedido entró al contenedor nuevo. | Positivo |
| **Tomado para el pedido** | `pick` | Se escaneó una caja para el pedido. | Ninguno |
| **Despachado** | `dispatch` | La caja salió de la bodega de origen. | Negativo |
| **Recibido** | `receive` | El destino aceptó la caja. | Positivo, en el destino |
| **Devuelto** | `return` | El destino disputó la caja y volvió al origen. | Positivo, en el origen |

Después de los movimientos van los **registros de custodia**:

| Registro | Cómo se lee |
| - | - |
| Entrega | "Entrega registrada · Ana Torres", o "Problema de entrega informado · Ana Torres: Llegó dañado" seguido de los detalles que se escribieron. |
| Recepción | "Recepción registrada · Luis Prado", luego "Aceptadas: BX-000123, BX-000124" y, en rojo, una línea por cada caja disputada, como "Disputada BX-000125: Dañada". |
| Cierre | "Pedido cerrado · Luis Prado". |

Si todavía no pasó nada, la sección dice "Todavía no pasó nada."

<Note>
  Los movimientos hechos sobre la caja original de una separación muestran **Caja que ya no está en el registro** en lugar de su código, porque la lista **Cajas** solo nombra el contenedor nuevo. Abre la caja original (consulta [Cajas y etiquetas](/docs/es/inventory/boxes)) para ver su propio historial.
</Note>

## Usarlo en auditorías y disputas

| Pregunta | Dónde mirar |
| - | - |
| ¿Qué cajas, lotes y vencimientos fueron a este destino? | **Cajas**: **Código de caja**, **Lote**, **Vence**. |
| ¿Quién tomó cada caja y cuándo? | Movimientos **Tomado para el pedido**. |
| ¿Quién despachó y cuándo salieron las cajas? | Movimientos **Despachado**. |
| ¿Quién confirmó la entrega y hubo algún problema? | El registro de entrega. |
| ¿Qué aceptó o disputó el destino y por qué? | El registro de recepción y luego los movimientos **Devuelto**. |
| ¿Dónde está ahora una caja disputada? | **Estado de la caja** (**En cuarentena** o **Activa**) y luego la página de la caja (consulta [Cajas y etiquetas](/docs/es/inventory/boxes)). |
| ¿Quién cerró el pedido? | El registro de cierre. |

Una revisión típica de una disputa:

<Steps>
  <Step title="Confirma la cadena de personas">
    Verifica que quien tomó, quien despachó y quien confirmó la entrega sean las personas esperadas de la parte de origen, y que la recepción la haya hecho la parte de destino.
  </Step>

  <Step title="Compara lo entregado con lo recibido">
    Cada caja de la entrega debe aparecer una vez en la recepción, como aceptada o disputada.
  </Step>

  <Step title="Sigue cada caja disputada">
    Busca su movimiento **Devuelto** y su **Estado de la caja** actual. Si volvió en cuarentena, decide qué hacer con ella desde su página de caja.
  </Step>

  <Step title="Revisa el lote si hace falta">
    Si el problema puede afectar a todo un lote, continúa en [Retiro de lote](/docs/es/inventory/lot-recall).
  </Step>
</Steps>

### Qué no muestra la pantalla

* El texto de **Evidencia del problema** escrito en la recepción. Se guarda, pero por ahora no se muestra en la consola ni lo devuelve la API.
* Las notas por caja de una disputa y la elección de cuarentena. La API devuelve ambas.
* La referencia del transportista escrita al despachar. `GET /v1/fulfillments` la devuelve como `carrierRef`.
* El registro de auditoría. Por ahora no hay una pantalla de auditoría en la consola.
* Una exportación. Para guardar los historiales de custodia fuera de muveya, léelos desde la API.

A estos registros solo se agregan datos: nada de este historial se puede editar ni borrar. Una caja disputada se corrige con un movimiento nuevo **Devuelto**, nunca cambiando el **Despachado**.

## Leerlo desde la API

La operación `GET /v1/fulfillments/{orderId}` devuelve el mismo historial de custodia para integraciones y reportes.

* **Autenticación:** una clave de API (`mvy_test_...`) en el encabezado `Authorization: Bearer`. Por ahora las claves de API no se crean desde la consola; consulta [Autenticación](/docs/es/api-reference/authentication).
* **Scope:** `fulfillment:read`. Consulta [Scopes](/docs/es/api-reference/scopes).
* **Cobertura:** toda la cuenta de clínica dental de la clave. Una clave no tiene filtro por sede.
* **Solo lectura:** los pasos de custodia (preparar, despachar, entregar, recibir, cerrar) no se pueden hacer por la API ni por MCP.

<CodeGroup>
  ```bash curl theme={null}
  curl https://api.muveya.com/v1/fulfillments/66f0c1a2b3c4d5e6f7a8b9c0 \
    -H "Authorization: Bearer $MUVEYA_API_KEY"
  ```
</CodeGroup>

### Respuesta

<ResponseField name="orderId" type="string" required>
  El id del pedido.
</ResponseField>

<ResponseField name="status" type="string" required>
  El estado de custodia: `allocating`, `allocated`, `picking`, `dispatched`, `delivered`, `exception`, `received`, `partially_fulfilled` o `closed`.
</ResponseField>

<ResponseField name="movements" type="object[]" required>
  Los movimientos de existencias del pedido, del más antiguo al más reciente. Cada uno tiene `movementId`, `type`, `boxId`, `catalogItemId`, `quantityDelta`, `actorId`, `occurredAt` y `recordedAt`, y cuando corresponde `reservedDelta`, `fromWarehouseId`, `toWarehouseId`, `reasonCode`, `secondActorId`, `idempotencyKey` y `correlationId`.
</ResponseField>

<ResponseField name="delivery" type="object">
  Presente cuando se confirmó la entrega: `actorUserId`, `deliveredAt`, `boxIds` y, si hubo un problema de entrega, `exception` con `reason` y `note` opcional.
</ResponseField>

<ResponseField name="receipt" type="object">
  Presente cuando se confirmó la recepción: `actorUserId`, `receivedAt`, `acceptedBoxIds` y `disputed`, una lista de `boxId`, `reason`, `quarantine` y `note` opcional.
</ResponseField>

<ResponseField name="closure" type="object">
  Presente cuando se cerró el pedido: `actorUserId` y `closedAt`.
</ResponseField>

```json Ejemplo de respuesta theme={null}
{
  "orderId": "66f0c1a2b3c4d5e6f7a8b9c0",
  "status": "partially_fulfilled",
  "movements": [
    {
      "movementId": "66f0c3000000000000000001",
      "type": "reserve",
      "boxId": "66e9a1000000000000000125",
      "catalogItemId": "66e1b2000000000000000045",
      "quantityDelta": 0,
      "reservedDelta": 10,
      "fromWarehouseId": "66e0f0000000000000000007",
      "actorId": "system:fulfillment",
      "occurredAt": "2026-09-14T13:02:11.000Z",
      "recordedAt": "2026-09-14T13:02:11.000Z"
    },
    {
      "movementId": "66f0c3000000000000000002",
      "type": "dispatch",
      "boxId": "66e9a1000000000000000125",
      "catalogItemId": "66e1b2000000000000000045",
      "quantityDelta": -10,
      "reservedDelta": -10,
      "fromWarehouseId": "66e0f0000000000000000007",
      "actorId": "66d7e4000000000000000031",
      "occurredAt": "2026-09-14T15:40:02.000Z",
      "recordedAt": "2026-09-14T15:40:02.000Z"
    },
    {
      "movementId": "66f0c3000000000000000003",
      "type": "return",
      "boxId": "66e9a1000000000000000125",
      "catalogItemId": "66e1b2000000000000000045",
      "quantityDelta": 10,
      "reservedDelta": 0,
      "reasonCode": "damaged",
      "actorId": "66d7e4000000000000000058",
      "occurredAt": "2026-09-15T09:12:44.000Z",
      "recordedAt": "2026-09-15T09:12:44.000Z"
    }
  ],
  "delivery": {
    "actorUserId": "66d7e4000000000000000031",
    "deliveredAt": "2026-09-15T08:55:10.000Z",
    "boxIds": ["66e9a1000000000000000125"]
  },
  "receipt": {
    "actorUserId": "66d7e4000000000000000058",
    "receivedAt": "2026-09-15T09:12:44.000Z",
    "acceptedBoxIds": [],
    "disputed": [
      {
        "boxId": "66e9a1000000000000000125",
        "reason": "damaged",
        "quarantine": true,
        "note": "Sello roto al llegar"
      }
    ]
  }
}
```

En qué se diferencia la API de la pantalla:

* Devuelve ids, no nombres ni códigos de caja. Lee el código y el estado de una caja con `GET /v1/inventory/boxes/{boxId}` (scope `inventory:read`), y un insumo con `GET /v1/catalog/items/{itemId}` (scope `catalog:read`).
* `actorId` y `actorUserId` son ids de integrantes. Las acciones que muveya hizo por su cuenta llevan `system:fulfillment`.
* El estado `allocating` puede aparecer por un momento mientras corre la reserva; la consola lo muestra como **Reservando existencias**.
* Responde `404` cuando el pedido no existe, pertenece a otra cuenta de clínica dental o todavía no tiene registro de custodia (un pedido aprobado cuyas existencias no están reservadas).
* Otras respuestas: `401` si la clave falta o no es válida, `403` si la clave no tiene `fulfillment:read`, `429` si la clave supera su límite de solicitudes. Consulta [Errores](/docs/es/api-reference/errors) y [Límites de uso](/docs/es/api-reference/rate-limits).

Para listar registros de custodia, usa `GET /v1/fulfillments` con el filtro opcional `status`, `limit` (de 1 a 200, 50 por defecto) y `cursor`. Cada elemento tiene `orderId`, `status`, `createdAt`, `updatedAt` y, cuando corresponde, `sourceWarehouseId`, `dispatchedAt` y `carrierRef`. Consulta [Paginación](/docs/es/api-reference/pagination).

<Info>
  La herramienta MCP `fulfillment.get_pick_list` necesita el permiso `fulfillment.pick`, que los scopes OAuth actuales de solo lectura no conceden, así que por ahora se rechaza en el endpoint `/mcp`. Consulta [Herramientas MCP](/docs/es/mcp/tools).
</Info>

## Páginas relacionadas

<CardGroup cols={2}>
  <Card title="Resumen de entregas" icon="truck" href="/docs/es/deliveries/overview">
    Ciclo de custodia, permisos y partes.
  </Card>

  <Card title="Entrega y recepción" icon="clipboard-check" href="/docs/es/deliveries/delivery-and-receipt">
    Cómo se crean los registros de entrega, recepción y cierre.
  </Card>

  <Card title="Cajas y etiquetas" icon="box" href="/docs/es/inventory/boxes">
    El historial completo de una caja.
  </Card>

  <Card title="Scopes" icon="key" href="/docs/es/api-reference/scopes">
    Qué scope necesita cada lectura.
  </Card>
</CardGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.