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

# Registro de cambios

> Notas de versión y actualizaciones para la API pública de Alvys, webhooks, servidor MCP e integraciones, con nuevas entradas añadidas cuando cambian las superficies.

<Update label="August 3, 2026" description="El servidor MCP ahora implementa la revisión de protocolo 2026-07-28, con indicaciones de seguridad en herramientas y errores de argumentos más claros. Los clientes existentes siguen funcionando." tags={["Added", "Changed", "Fixed", "MCP"]}>
  El servidor MCP de Alvys ahora implementa la revisión de protocolo MCP **2026-07-28** — la revisión más grande del protocolo desde su lanzamiento. Las revisiones anteriores siguen aceptándose, por lo que **no se requiere ninguna acción para los clientes existentes**.

  <Note>
    **Nada que configurar.** Los clientes y servidores MCP negocian la revisión de protocolo automáticamente al conectar. La URL del servidor, el catálogo de herramientas y los alcances son idénticos en todas las revisiones — la revisión negociada cambia la mecánica del protocolo, no lo que tu agente puede hacer.
  </Note>

  ## Soporte de revisiones de protocolo

  | MCP revision | Supported | Notes                                                                              |
  | ------------ | --------- | ---------------------------------------------------------------------------------- |
  | `2026-07-28` | Yes       | Actual. Sin sesión — la revisión viaja en cada solicitud.                          |
  | `2025-11-25` | Yes       | Negociada mediante el handshake `initialize`.                                      |
  | `2025-06-18` | Yes       | Negociada mediante el handshake `initialize`.                                      |
  | `2025-03-26` | Yes       | Negociada mediante el handshake `initialize`.                                      |
  | `2024-11-05` | Yes       | Negociada mediante el handshake `initialize`. Obsoleta por MCP, aún aceptada aquí. |

  Si un cliente no logra conectar, es muy poco probable que la revisión de protocolo sea la causa — comprueba primero la autenticación y la selección de organización.

  ## Added

  * **Indicaciones de seguridad en herramientas.** Cada herramienta ahora anuncia `annotations` de MCP — `readOnlyHint`, `destructiveHint`, `idempotentHint` y `openWorldHint` — derivadas de la misma clasificación Read/Write/Destructive que el servidor aplica, de modo que la indicación anunciada siempre coincide con la política aplicada. Los clientes las usan para decidir cuándo pedir confirmación a un humano antes de ejecutar una herramienta. La superficie beta es de solo lectura, por lo que cada herramienta actualmente visible está marcada con `readOnlyHint: true` y `destructiveHint: false`; las indicaciones importan cuando se habiliten las herramientas de escritura, y ya están en su lugar con antelación.
  * **Guía de uso del servidor.** El servidor publica `instructions` en lenguaje natural que describen cómo usar la superficie — que la visibilidad de herramientas es fija por despliegue, que los parámetros desconocidos se rechazan en lugar de ignorarse, y que las búsquedas son basadas en 0 y paginadas. Los clientes que muestran las instrucciones del servidor pasarán esto al modelo automáticamente.

  ## Changed

  * **Orden estable de herramientas.** `tools/list` y `prompts/list` devuelven entradas ordenadas por nombre, de modo que el catálogo ya no varía entre solicitudes. Esto hace fiable el almacenamiento en caché del lado del cliente y mejora las tasas de acierto de caché de prompts cuando la lista de herramientas se incluye en el contexto del modelo.
  * **`GET` y `DELETE` en `/mcp` devuelven `405 Method Not Allowed`.** Estos eran los verbos de sesión heredados — `GET` abría un flujo servidor-a-cliente y `DELETE` finalizaba una sesión. La revisión `2026-07-28` no usa sesiones, por lo que ninguno se ofrece. Ahora responden `405` (una señal de capacidad) en lugar de `400` o `401`, de modo que un cliente que sondea soporte de sesión obtiene una respuesta inequívoca sin token.
  * **`offline_access` ya no se anuncia en `scopes_supported`.** Un token de actualización no es un requisito de este recurso, por lo que los metadatos del recurso protegido ya no lo listan. Los clientes que quieran un token de actualización siguen solicitándolo al servidor de autorización como antes. Esto acorta la pantalla de consentimiento.

  ## Fixed

  * **Los errores de argumentos son accionables en lugar de genéricos.** Un argumento obligatorio faltante, o uno del tipo incorrecto (por ejemplo `page: "not-an-int"`), antes devolvía `An error occurred.` — indistinguible de un fallo del servidor. Ahora devuelven un error estructurado `[invalid_params]` que nombra el parámetro, de modo que un agente puede corregir la llamada y reintentar. Esto cubre tanto herramientas como prompts.
  * **Errores de argumentos en prompts.** `prompts/get` con un argumento obligatorio faltante devolvía el mismo error genérico. Ahora devuelve `invalid_params` nombrando el argumento.
  * **Las solicitudes mal formadas devuelven un cuerpo de error adecuado.** Una solicitud JSON-RPC mal formada ahora devuelve `400` con un error JSON-RPC en lugar de un `500` vacío.

  <Tip>
    ¿Usas un cliente MCP oficial (Claude.ai, Claude Desktop, Cursor, `mcp-remote`)? No necesitas hacer nada — la negociación de revisión y los nuevos encabezados de solicitud se gestionan por ti. Solo los clientes HTTP hechos a mano que fijan una revisión de protocolo necesitan tener en cuenta la tabla anterior.
  </Tip>
</Update>

<Update label="July 28, 2026" description="Las rutas desconocidas de la Public API devuelven 404, no 401" tags={["Fixed", "Authentication"]}>
  ### ¿Qué cambió?

  Las solicitudes a una ruta de la Public API que no existe — por ejemplo un nombre de controlador con error tipográfico o un endpoint retirado — devuelven **404 Not Found**. **No** devuelven **401 Unauthorized**.

  **401 Unauthorized** sigue significando que el token de acceso falta o no es válido. Consulta [Response Codes](/en/api/guides/response-codes).

  ### ¿Qué debo hacer?

  No se requieren cambios en el cliente si ya tratas las rutas desconocidas como 404. Si recientemente trataste 401 inesperados en URLs incorrectas como fallos de credenciales, verifica primero la ruta de la solicitud contra la [referencia de la API](/en/api/reference/authentication).
</Update>

<Update label="July 24, 2026" description="Catálogo de herramientas MCP: la escritura de stop-status se divide en tres herramientas, nueva trucks_events_search, correcciones de descubrimiento y autorización" tags={["Added", "Changed", "Fixed", "MCP"]}>
  ## Herramientas MCP

  * **Added** `trips_record_arrival` (Write · `stop:update`) — registra un evento de llegada en una parada del viaje. Envuelve `PUT /api/p/v1/trips/{tripId}/stops/{stopId}/arrival`.
  * **Added** `trips_record_departure` (Write · `stop:update`) — registra un evento de salida en una parada del viaje. El servidor exige que exista primero una llegada. Envuelve `PUT /api/p/v1/trips/{tripId}/stops/{stopId}/departure`.
  * **Added** `trips_update_stop_appointment` (Write · `stop:update`) — actualiza la cita (o ventana FCFS) en una parada del viaje. `scheduleType` debe ser `APPT` o `FCFS`; `appointmentDate` es obligatorio cuando `scheduleType=APPT`, y `windowBegin` es obligatorio cuando `scheduleType=FCFS`. Envuelve `PUT /api/p/v1/trips/{tripId}/stops/{stopId}/appointment`.
  * **Removed** `trips_update_stop_status` — la herramienta combinada única se reemplaza por las tres herramientas específicas anteriores. Quienes llamen deben migrar a la herramienta específica de la acción que quieran realizar.
  * **Added** `trucks_events_search` (Read · `truck:read`) — obtiene eventos de camión (mantenimiento, programación, disponibilidad) para uno o más camiones en un rango de fechas, en espejo de `drivers_events_search`. Pasa `truckIds` (ids de camión de Alvys, no números de unidad) y un `startDate`; `endDate` es opcional. Devuelve una lista plana de eventos, sin paginación — una lista vacía significa que no hubo eventos en el rango.

  ## Corregido

  * **Los clientes MCP basados en navegador pueden completar el descubrimiento.** Los endpoints de metadatos del recurso protegido y `/mcp` ahora responden a solicitudes cross-origin y a preflights OPTIONS, así que un cliente que ejecuta OAuth guiado en el navegador (por ejemplo MCP Inspector) puede terminar el handshake en lugar de fallar en el preflight.
  * **Autorización consistente para tokens con solo permisos de estados de liquidación.** Un token de usuario que solo lleva permisos de estados de liquidación ya no pasa las herramientas de lectura `carriers_*` y `drivers_*` en el borde MCP para luego ser rechazado por la Public API. Esas herramientas ahora exigen los mismos permisos de lectura de transportista y conductor que aplican sus endpoints subyacentes, de modo que ambos lados coinciden en el resultado.

  <Note>
    Los endpoints subyacentes de la Public API no cambian — lo que cambió es el catálogo de herramientas MCP y el propio comportamiento de autorización y descubrimiento del servidor MCP.
  </Note>
</Update>

<Update label="July 23, 2026" description="MCP: argumentos estrictos, paginación basada en 0, formas de argumentos alineadas con la Public API" tags={["Changed", "Breaking", "MCP"]}>
  El servidor MCP de Alvys ahora es más estricto con los argumentos de las herramientas y alinea las formas de paginación y filtros con la Public API, de modo que las llamadas se portan 1:1 entre ambas. Dos de estos cambios son **breaking** para quien haya automatizado contra la fachada MCP anterior.

  <Warning>
    **Breaking — la paginación ahora es basada en 0.** El parámetro `page` de cada herramienta de búsqueda tiene valor predeterminado `0` y se pasa a la Public API sin cambios. Si tu agente o script actualmente envía `page=1` para obtener la primera página, ahora obtiene la **segunda** página. Actualiza a los llamadores para empezar en `page=0`. `page=-1` (o cualquier valor negativo) se rechaza con `[invalid_params]`.
  </Warning>

  <Warning>
    **Breaking — se rechazan parámetros desconocidos.** El SDK de MCP antes enlazaba argumentos por nombre y descartaba en silencio las claves desconocidas, así que un filtro mal escrito o no admitido (p. ej. `customers_search name="Colortech"`) devolvía resultados seguros pero incorrectos — la lista completa sin filtrar — en lugar de un error. Cada herramienta ahora valida las claves de argumentos contra su esquema de entrada anunciado antes de ejecutarse, incluidas las claves anidadas dentro de rangos de fechas y elementos de arreglos, y devuelve un error estructurado `[invalid_params]` que nombra las claves rechazadas y la lista de parámetros válidos. Migra a los llamadores que dependían de que las claves desconocidas se ignoraran en silencio; el mensaje de error indica exactamente qué claves eliminar o renombrar.
  </Warning>

  ## Qué cambió

  * **Paginación basada en 0 en cada herramienta de búsqueda.** `page` tiene valor predeterminado `0` y las respuestas devuelven el `page` de la solicitud para que los agentes puedan controlar su propio paginador. `pageSize` sigue teniendo valor predeterminado `25` (máx. `100`).
  * **Validación estricta de argumentos.** Las claves desconocidas — en el nivel superior o anidadas dentro de un objeto de rango de fechas o elemento de arreglo — devuelven `[invalid_params]` nombrando las claves ofensivas y la lista completa de parámetros válidos de la herramienta.
  * **Filtros de arreglo, coincidiendo con la Public API.** Los filtros que mapean a campos de arreglo de `/search` ahora se declaran como arreglos en la herramienta para que puedas pasar uno o varios valores en una sola llamada.
  * **Objetos estructurados de rango de fechas.** Los filtros de rango de fechas ahora son objetos únicos `{ start, end }` usando los mismos nombres de parámetros que usa la Public API. Un `end` sin un `start` se rechaza de entrada. `invoices_search` sigue exigiendo al menos un filtro que no sea de fecha junto con un rango (igual que la Public API); `trips_search` acepta un rango como su único filtro.

  ## Herramientas afectadas

  | Tool                       | Parameters changed                                                                                                                                                                                                                                                                               |
  | -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
  | `customers_search`         | `status` (string) → `statuses` (array); `createdFrom` / `createdTo` → `createdDateRange` `{ start, end }`; `page` default `1` → `0`                                                                                                                                                              |
  | `carriers_search`          | `status` (string) → `status` (array); `mcNumber` → `mcNumbers` (array); `dotNumber` → `dotNumbers` (array); `page` default `1` → `0`                                                                                                                                                             |
  | `loads_search`             | `status` (string) → `status` (array); `loadNumber` → `loadNumbers` (array, max 50); `orderNumber` → `orderNumbers` (array, max 50); `page` default `1` → `0`                                                                                                                                     |
  | `trips_search`             | `status` (string) → `status` (array); `loadNumber` → `loadNumbers` (array, max 50); `tripNumber` → `tripNumbers` (array, max 50); `pickupFrom` / `pickupTo` → `pickupDateRange` `{ start, end }`; `deliveryFrom` / `deliveryTo` → `deliveryDateRange` `{ start, end }`; `page` default `1` → `0` |
  | `drivers_search`           | `status` (string) → `status` (array); `page` default `1` → `0`                                                                                                                                                                                                                                   |
  | `drivers_events_search`    | `driverId` (single) → `driverIds` (array; pass several for a fleet-wide query)                                                                                                                                                                                                                   |
  | `trucks_search`            | `unitNumber` → `truckNumber`; `status` (string) → `status` (array); `page` default `1` → `0`                                                                                                                                                                                                     |
  | `trailers_search`          | `unitNumber` → `trailerNumber`; `status` (string) → `status` (array); `page` default `1` → `0`                                                                                                                                                                                                   |
  | `invoices_search`          | `status` (string) → `status` (array); `loadNumber` → `loadNumbers` (array, max 50); `orderNumber` → `orderNumbers` (array, max 50); `invoicedFrom` / `invoicedTo` → `invoicedDateRange` `{ start, end }`; `paidFrom` / `paidTo` → `paidDateRange` `{ start, end }`; `page` default `1` → `0`     |
  | `fuel_transactions_search` | `truckId` → `truckNumber`; `from` / `to` → `transactionRange` `{ start, end }`; `page` default `1` → `0`                                                                                                                                                                                         |
  | `tenders_search`           | `status` (string) → `status` (array); `page` default `1` → `0`                                                                                                                                                                                                                                   |
  | `deductions_search`        | `page` default `1` → `0`                                                                                                                                                                                                                                                                         |

  ## Migración

  1. **Renombra cualquier parámetro renombrado.** En particular: `unitNumber` → `truckNumber` / `trailerNumber` (en `trucks_search` / `trailers_search`), `truckId` → `truckNumber` (en `fuel_transactions_search`), y las formas singulares `mcNumber` / `dotNumber` / `loadNumber` / `orderNumber` / `tripNumber` / `driverId` → sus formas plurales de arreglo en las herramientas de búsqueda listadas arriba.
  2. **Envuelve los filtros de un solo valor en un arreglo.** `status: "Active"` → `status: ["Active"]`, `mcNumber: "12345"` → `mcNumbers: ["12345"]`, y así sucesivamente.
  3. **Compacta los pares de fechas en objetos `{ start, end }`** usando los nuevos nombres de parámetros (`createdDateRange`, `pickupDateRange`, `deliveryDateRange`, `invoicedDateRange`, `paidDateRange`, `transactionRange`).
  4. **Reduce `page` en uno.** `page=1` (antigua primera página) → `page=0`. Si tu código calcula `page` desde un índice de UI, resta `1` en el punto de llamada.
  5. **Elimina cualquier clave no reconocida.** Si una llamada ahora devuelve `[invalid_params]`, el mensaje de error lista tanto las claves rechazadas como el conjunto de parámetros válidos — alinea con esa lista.

  Los prompts guiados (`carrier_onboarding_v1`, `settlement_reconciliation_v1`) se actualizaron para referenciar los nuevos nombres de parámetros. La cobertura de herramientas de lectura, los permisos y los endpoints no cambian en lo demás.

  Consulta [Available MCP Tools](/en/api/guides/available-mcp-tools#conventions) para las convenciones completas y un ejemplo de payload `[invalid_params]`.
</Update>

<Update label="July 23, 2026" description="Credenciales de API con alcance por filial" tags={["Added", "Authentication"]}>
  Las credenciales de API ahora pueden **limitarse a filiales específicas**. El token de acceso de una credencial con alcance está limitado a los datos de las filiales para las que se emitió — en todos los endpoints de lectura *y* escritura de Public API, incluidos los webhooks.

  ### Qué cambió

  Anteriormente, cada credencial de API tenía acceso a todo el tenant: cualquier token podía leer y modificar datos de cualquier filial de su empresa. Las selecciones de filial durante la creación de credenciales se almacenaban pero no se aplicaban.

  Ahora, cuando se crea una credencial con una o más filiales seleccionadas, ese alcance se incorpora en el token de acceso y se aplica en cada solicitud.

  ### Cómo funciona el alcance del token

  Cuando solicita un token de acceso, Alvys añade una nueva reclamación al token:

  ```
  https://alvys.com/claims/app/subsidiaries
  ```

  La reclamación se añade automáticamente al emitir el token y restringe el acceso de la credencial solo a las filiales que se le hayan otorgado. Se evalúa en cada solicitud de API, sin configuración adicional.

  **Reglas de alcance:**

  | Configuración de su credencial               | Reclamación en el token | Qué puede hacer el token                 |
  | -------------------------------------------- | ----------------------- | ---------------------------------------- |
  | Con alcance a filiales específicas (hasta 3) | Los IDs de las filiales | Solo ver y editar datos de esas filiales |
  | **Todas las filiales** seleccionadas         | `*`                     | Acceder a cada filial de su empresa      |
  | Ninguna filial seleccionada                  | `*`                     | Acceder a cada filial de su empresa      |
  | Credenciales creadas antes de esta versión   | `*`                     | Sin cambios — mismo acceso que antes     |

  ### Qué puede ver y hacer un token con alcance

  **Lecturas** — los endpoints de búsqueda y listado devuelven solo registros de las filiales de la credencial, más registros sin asignación de filial (datos a nivel de tenant). Las solicitudes get-by-ID de un registro fuera del alcance devuelven `404 Not Found`, exactamente como si el registro no existiera.

  **Escrituras** — un token con alcance no puede crear, actualizar ni eliminar registros fuera de sus filiales. Las escrituras fuera de alcance devuelven `404 Not Found` — la misma respuesta que un registro inexistente, de modo que una credencial con alcance no puede sondear la existencia de datos de otra filial. Esto cubre actualizaciones de carga, notas y documentos, asignación/despacho de viaje, llegadas/salidas/citas de paradas, check calls, actualizaciones y eliminaciones de clientes, deducciones, pagos y financiación de facturas, y cargas de documentos de activos.

  **Webhooks** — las suscripciones de webhook están vinculadas a filial. Una credencial con alcance solo puede crear, listar, gestionar y leer registros de entrega de webhooks de sus propias filiales, y solo puede suscribirse a eventos de esas filiales.

  ### Entidades con alcance

  El alcance por filial aplica a: Loads, Trips (incluidas paradas y check calls), Invoices, Customers, Deductions, Fuel transactions, Tolls, Drivers, Trucks, Trailers, Driver Settlement Statements, Carrier Settlement Statements y Webhooks. Carriers y Tenders no tienen alcance por filial.

  ### Cambios en códigos de respuesta

  Un código de respuesta cambió como parte de este trabajo: `POST /api/p/v{version}/trips/{tripId}/assign` con un **ID de viaje desconocido** ahora devuelve `404 Not Found` (antes `400 Bad Request`). Esto alinea assign con los demás endpoints de viaje y es necesario para la garantía de no filtración de existencia anterior. No cambiaron otros códigos de estado.

  ### Compatibilidad hacia atrás

  Las credenciales e integraciones existentes no se ven afectadas. Los tokens emitidos desde credenciales sin selección de filial — incluidas todas las credenciales creadas antes de esta versión — siguen siendo a nivel de tenant. El alcance solo aplica cuando selecciona filiales explícitamente en una credencial.

  ### Crear una credencial con alcance

  1. Vaya a **Settings → API Keys**
  2. Haga clic en **New credential**
  3. Seleccione **permissions** y elija las **subsidiaries** a las que la credencial puede acceder — hasta 3 filiales específicas, o **All subsidiaries** para acceso a todo el tenant
  4. Haga clic en **Generate** y almacene el Client ID y Secret de forma segura

  Los tokens solicitados con estas credenciales mediante el flujo estándar OAuth 2.0 Client Credentials llevarán automáticamente el alcance de filial.
</Update>

<Update label="July 22, 2026" description="Tipo de transacción Escrow en estados de liquidación de conductor, acceso de lectura con token de usuario" tags={["Added", "Fixed", "Driver Settlement Statements", "Authentication", "MCP"]}>
  ## Public API + MCP: acceso con token de usuario a endpoints de lectura

  * **Fixed** los tokens interactivos (user-PKCE) fallaban en `load:read`, `stop:read`, `trip:read`, `visibility:read` y `carrier:read` en la Public API y MCP para usuarios que de otro modo tenían privilegios. Estos endpoints comprobaban permisos internos (`ViewLoads`, `Carrier` base) que ningún registro de usuario real lleva. Cualquier usuario autenticado del tenant ahora pasa la mitad de token de usuario de esas comprobaciones de lectura, coincidiendo con el gating de roles en la app. Los tokens machine-to-machine no cambian — siguen requiriendo el alcance OAuth correspondiente. Cada endpoint de escritura conserva su comprobación real de permisos.

  ## `POST /api/p/v{version}/driver-settlement-statements/search` y `GET /api/p/v{version}/driver-settlement-statements/{number}`

  * **Added** `TransactionType` en la respuesta `LineItems[]`. Solo se rellena cuando `Category` es `Escrow`; `null` para cualquier otro ítem de línea.
    * `"Deposit"` — dinero movido **hacia** la cuenta de escrow del conductor. Aparece como un `Amount` negativo.
    * `"Withdrawal"` — dinero movido **fuera** de la cuenta de escrow. Aparece como un `Amount` positivo.
  * Aditivo y no breaking. Los consumidores existentes ven un campo nullable nuevo. Los totales y todos los demás campos no cambian. Esta es hoy la única superficie de la Public API que devuelve ítems de línea de escrow; `POST /api/p/v{version}/deductions/search` no lo hace.
</Update>

<Update label="July 13, 2026" description="Corrección del estado de viaje en pago al transportista" tags={["Fixed", "Invoices", "MCP"]}>
  ## `POST /api/p/v{version}/invoices/carrier-payments`

  * **Se eliminó** `MarkAsPaid` del cuerpo de la solicitud. El campo solo existía para forzar un estado de viaje `Paid`, que Alvys no usa. Los llamadores existentes que aún envían `markAsPaid` no se ven afectados — el campo se ignora.
  * **Se corrigió** el estado del viaje en la respuesta: cuando los pagos registrados cubren totalmente el importe a pagar al transportista, el viaje ahora transiciona a **`Completed`** en lugar de **`Paid`**. Los pagos parciales dejan el estado del viaje sin cambios.
  * El campo `Status` de la respuesta refleja el estado actual del viaje después de aplicar el pago.

  ## MCP: `invoices_record_carrier_payment`

  * **Se eliminó** el parámetro `markAsPaid` (mismo comportamiento que el cambio en la API pública anterior).

  <Note>
    Los viajes históricos aún pueden tener un estado `Paid` de antes de esta corrección. Se planea un backfill de datos único por separado.
  </Note>
</Update>

<Update label="July 13, 2026" description="Diferencias de cambio en webhooks: vea exactamente qué cambió en eventos de carga y viaje" tags={["Added", "Webhooks"]}>
  Los webhooks de carga y viaje ahora pueden indicarle exactamente qué cambió. Los eventos `load.changed` y `trip.changed` llevan un `data.diff` opcional — una lista de tipos de cambio con nombres de dominio (por ejemplo `StatusChanged`, `RateChanged`, `AppointmentChanged`) y, de forma opcional, los valores anteriores de cada campo cambiado. Reaccione al cambio exacto que importa y aplique solo el delta, en lugar de calcular usted mismo las diferencias entre instantáneas completas.

  **¿Qué hay de nuevo?**

  Los webhooks `load.changed` y `trip.changed` ahora llevan un nodo `data.diff` opcional que indica **qué cambió** en el registro — y, si lo activa, **cuál era el valor anterior**. Ya no tiene que calcular usted mismo el delta entre instantáneas sucesivas para reaccionar a un cambio.

  **¿Qué cambió?**

  Anteriormente, `load.changed` y `trip.changed` entregaban solo la instantánea actual completa en `data`. Los consumidores tenían que almacenar en caché la carga útil anterior y calcular su propio delta para saber si un cambio era relevante. Cada evento ahora puede incluir `data.diff` con dos partes independientes:

  * `data.diff.changes` — un arreglo de tipos de cambio con nombres de dominio (por ejemplo `StatusChanged`, `RateChanged`, `StopReordered`, `AppointmentChanged`). Se entrega a todos los suscriptores cuando algo significativo cambió. Los cambios de subentidad llevan un `target` — `{ "type": "Stop" | "Field", "id": "<stableId>" }`.
  * `data.diff.previousAttributes` — el valor anterior de cada campo cambiado visible en la respuesta pública, con claves 1:1 con la instantánea. Las colecciones con clave (paradas, referencias, líneas de cargo) difieren por `id` estable. **Opcional por suscripción.**

  **Sobre del evento**

  ```json theme={null}
  {
    "type": "load.changed",
    "data": {
      "load": { "...": "instantánea actual completa" },
      "diff": {
        "changes": [
          { "kind": "StatusChanged" },
          { "kind": "AppointmentChanged", "target": { "type": "Stop", "id": "abc123" } }
        ],
        "previousAttributes": { "...": "valores anteriores (opcional)" }
      }
    }
  }
  ```

  `data.diff` está presente solo en `load.changed` / `trip.changed` — **nunca** en `*.status.changed`, y se **omite en el primer evento (creación)** donde no hay estado previo.

  <Warning>
    **Trate `changes` solo como pista de filtrado.** El vocabulario está curado y puede crecer — ignore siempre los tipos de cambio que no reconozca, y nunca asuma que la instantánea no cambió solo porque falta un tipo.
  </Warning>

  **Cómo habilitar valores anteriores**

  `data.diff.changes` se entrega automáticamente. `data.diff.previousAttributes` es opcional:

  * **Dashboard:** active **Include previous values** en el webhook.

      <img src="https://mintcdn.com/alvys/MPqgFq1pceM5E4R4/images/migrated/6ca0d7874cd3.png?fit=max&auto=format&n=MPqgFq1pceM5E4R4&q=85&s=2d681113b69646ccb2a213f14f269f09" alt="" width="688" height="113" data-path="images/migrated/6ca0d7874cd3.png" />
  * **API:** establezca `IncludePreviousAttributes: true` al crear o actualizar la suscripción (predeterminado `false`).&#x20;

  **Endpoints afectados**

  `POST /p/v1.0/webhooks` y `PUT /p/v1.0/webhooks/{id}` aceptan la nueva marca `IncludePreviousAttributes`. La entrega de eventos en suscripciones `load.changed` / `trip.changed` existentes es retrocompatible — `data.diff` es aditivo.

  **¿Por qué?**

  Los integradores que reflejan estado ahora pueden aplicar solo el delta en lugar de reimportar todo el registro en cada evento — menor costo de procesamiento, pistas de auditoría más limpias y la capacidad de filtrar por el cambio de negocio exacto que importa.
</Update>

<Update label="July 10, 2026" description="Los check calls ahora están disponibles en la Public API" tags={["Added", "Trips", "Visibility"]}>
  ### ¿Qué hay de nuevo?

  Los check calls — actualizaciones de estado del conductor registradas contra un viaje — ahora se pueden leer y registrar a través de la Public API. Las plataformas de seguimiento y los proveedores de visibilidad pueden enviar actualizaciones de ubicación a Alvys y leer el historial completo de check calls sin entrada manual.

  ### ¿Qué cambió?

  Anteriormente, los check calls solo eran visibles y editables dentro de la plataforma Alvys.

  Ahora, la Public API incluye dos nuevos endpoints:

  ```http theme={null}
  GET  /api/p/v{version}/trips/{tripId}/check-calls
  POST /api/p/v{version}/trips/{tripId}/check-calls
  ```

  * **List trip check calls** — devuelve cada check call registrado en el viaje.
  * **Log a trip check call** — registra un nuevo check call con un `description` obligatorio más `activity`, `driverId`, `location` estructurada (coordenadas incluidas) y `setpointTemperature` / `returnTemperature` de reefer opcionales.

  ### El cuerpo de respuesta incluye

  * Core: `Id`, `LoadNumber`, `TripId`, `TripNumber`, `Description`
  * Status: `Activity`, `ResponseType`, `DriverName`
  * Location: dirección estructurada con coordenadas
  * Reefer: `SetpointTemperature`, `ReturnTemperature`
  * Audit: `CreatedAt`, `CreatedBy`

  Los campos opcionales no establecidos se devuelven como `null` (no cadenas vacías), de modo que los consumidores pueden distinguir "no proporcionado" de "explícitamente vacío".

  ### ¿Por qué?

  Los check calls son el latido de la visibilidad en tránsito. Exponerlos mediante la Public API permite que las integraciones de seguimiento escriban actualizaciones de estado directamente en el viaje y que los sistemas posteriores consuman un historial único y consistente.
</Update>

<Update label="July 6, 2026" description="Nuevos endpoints de la Public API para estados de liquidación" tags={["Added", "Driver Settlement Statements", "Carriers"]}>
  Hemos añadido soporte en la Public API para estados de liquidación finalizados de conductores, owner-operators y transportistas. Los partners ahora pueden obtener encabezados de estado, totales y detalle completo de partidas de forma programática — facilitando la creación de informes personalizados y flujos de conciliación sin exportar manualmente el informe "Statements List and Items".

  ### Qué hay de nuevo

  * Buscar estados de liquidación finalizados de conductores y owner-operators con paginación, partidas y totales.
  * Buscar estados de liquidación finalizados de transportistas con paginación, desgloses por viaje, partidas, pagos y totales.
  * Obtener un único estado de liquidación de conductor, owner-operator o transportista por número de estado.
  * Filtrar búsquedas de estados por rango de fechas del estado, tipo de conductor, transportista y subsidiaria.

  ### Qué cambia

  * Esta versión es aditiva y retrocompatible.
  * Solo se devuelven estados finalizados de la pestaña **Statements**. Se excluyen los estados Open y Draft.
  * Los estados de liquidación de conductor pueden incluir estados `Failed`; se identifican mediante el campo `Status`.
  * Los estados de liquidación de transportista excluyen estados `Failed` y `Deleted`.
  * `StatementDateRange` es obligatorio para las solicitudes de búsqueda. Tanto `Start` como `End` deben proporcionarse y se interpretan como días de calendario UTC inclusivos.
  * El filtro `DriverType` de conductor acepta `COMPANY`, `OWNER_OPERATOR` o `CONTRACTOR`, sin distinguir mayúsculas/minúsculas, coincidiendo con el endpoint `/drivers`.
  * Los valores monetarios se devuelven como objetos `{ Amount, Currency }`.
  * El acceso usa los alcances existentes:

    * `driver:read` para estados de liquidación de conductor
    * `carrier:read` para estados de liquidación de transportista

  ### Endpoints afectados

  * `POST /p/v1.0/driver-settlement-statements/search` (nuevo) — busca estados de liquidación finalizados de conductores y owner-operators.
  * `GET /p/v1.0/driver-settlement-statements/{number}` (nuevo) — obtiene un único estado de liquidación de conductor u owner-operator por número de estado.
  * `POST /p/v1.0/carrier-settlement-statements/search` (nuevo) — busca estados de liquidación finalizados de transportistas.
  * `GET /p/v1.0/carrier-settlement-statements/{number}` (nuevo) — obtiene un único estado de liquidación de transportista por número de estado.
</Update>

<Update label="June 19, 2026" description="Nuevos endpoints de la API pública para viajes y transportistas" tags={["Added", "Carriers", "Trips"]}>
  Hemos añadido soporte en la API pública para asignar transportistas a viajes, despachar viajes, buscar viajes por equipo asignado, actualizar el estado de transportistas y leer contactos de transportistas — para que los partners puedan ejecutar más del flujo de despacho y transportistas de forma programática.

  ## Qué hay de nuevo

  * **Asignar un transportista a un viaje** — asigna un transportista y, opcionalmente, un conductor, camión y remolque a un viaje.
  * **Despachar un viaje** — despacha un viaje cubierto para que el despacho pueda dispararse desde tu propio flujo.
  * **Filtrar viajes por conductor, camión o remolque** — acota la búsqueda de viajes a un conductor específico o pieza de equipo.
  * **Actualizar el estado de un transportista** — establece el estado de un transportista (por ejemplo, Active, Do Not Load) para mantener los registros sincronizados con tus sistemas de cumplimiento y evaluación.
  * **Contactos de transportista en la respuesta de transportista** — lee los datos de contacto del transportista sin llamadas adicionales.

  ## Qué cambia

  * Todos los cambios son aditivos y retrocompatibles.
  * Los nuevos filtros de viaje (`driverId`, `truckId`, `trailerId`) son opcionales. Cada uno es válido por sí mismo o junto con los parámetros de búsqueda existentes; `driverId` coincide con asignaciones primarias, secundarias y de owner-operator.
  * Las respuestas de transportista ahora incluyen una colección `Contacts` (nombre, correo, teléfono, móvil, título y una marca de contacto principal) tanto en las respuestas de get-by-id como de búsqueda.
  * Asignar un transportista requiere `carrierId` y `dispatcherId`; `driver2Id` no se puede enviar sin `driver1Id`. Los activos se referencian por id — resuélvelos primero mediante sus endpoints de búsqueda.
  * El despacho requiere que el viaje esté **Covered** (transportista y activos asignados); de lo contrario, la solicitud se rechaza.
  * Actualizar el estado de un transportista admite concurrencia optimista mediante el encabezado `If-Match` y devuelve un nuevo `ETag` para la siguiente actualización.

  ## Endpoints afectados

  * `POST /p/v1.0/trips/{tripId}/assign` *(nuevo)* — asigna un transportista y activos opcionales; devuelve el viaje actualizado.
  * `POST /p/v1.0/trips/{tripId}/dispatch` *(nuevo)* — despacha un viaje cubierto; devuelve el viaje actualizado.
  * `POST /p/v1.0/trips/search` *(actualizado)* — ahora acepta los filtros `driverId`, `truckId` y `trailerId`.
  * `PATCH /p/v1.0/carriers/{carrierId}/status` *(nuevo)* — actualiza el estado de un transportista; devuelve `204 No Content` con un nuevo `ETag`.
  * `GET /p/v1.0/carriers/{id}` y `POST /p/v1.0/carriers/search` *(actualizados)* — las respuestas ahora incluyen `Contacts`.

  <br />
</Update>

<Update label="June 19, 2026" description="Endpoints de tender ahora disponibles en Public API" tags={["Added", "Tenders"]}>
  **Fecha de lanzamiento:** noviembre de 2025 (ingesta de tender), 19 de junio de 2026 (disponibilidad pública)

  ### ¿Qué hay de nuevo?

  Public API ahora incluye un conjunto completo de endpoints de **Tender**, que cubren todo el ciclo de vida del tender — crear, actualizar, cancelar, buscar y responder (aceptar / rechazar). Introducida originalmente como un complemento centrado en EDI, la API de Tenders ahora forma parte del grupo Swagger público estándar y está disponible para todos los consumidores de Public API.

  ### ¿Qué cambió?

  Anteriormente, las operaciones de tender solo estaban disponibles mediante integraciones EDI o como un complemento restringido.

  Ahora, Public API incluye:

  ```http theme={null}
  POST /api/p/v{version}/tenders/search
  GET  /api/p/v{version}/tenders/{tenderId}
  POST /api/p/v{version}/tenders
  POST /api/p/v{version}/tenders/update
  POST /api/p/v{version}/tenders/cancel
  POST /api/p/v{version}/tenders/{tenderId}/accept
  POST /api/p/v{version}/tenders/{tenderId}/accept-updates
  POST /api/p/v{version}/tenders/{tenderId}/accept-cancel
  POST /api/p/v{version}/tenders/{tenderId}/reject
  ```

  * **Buscar y obtener** — consulte tenders y recupere el detalle completo del tender.
  * **Crear / actualizar / cancelar** — ingiera tenders de carga (incluidos los originados en EDI 204) de forma programática.
  * **Aceptar / rechazar** — responda a un tender; aceptar crea la carga correspondiente en Alvys.
  * **Aceptar actualizaciones / aceptar cancelación** — aplique una actualización o cancelación de tender entrante a la carga vinculada.

  Se complementa con los **eventos webhook** del ciclo de vida del tender (`tender.received`, `tender.updated`, `tender.cancelled` y eventos relacionados) anunciados por separado — suscríbase a webhooks para notificación en tiempo real y luego actúe sobre el tender mediante estos endpoints.

  ### ¿Por qué?

  El tendering es la puerta de entrada del ciclo de vida de la carga. Exponerlo en Public API permite a brokers, shippers y plataformas de integración enrutar carga hacia Alvys — y responder a ella — sin requerir un pipeline EDI tradicional.
</Update>

<Update label="June 3, 2026" description="Actualizar el Order Number de una carga mediante la API pública" tags={["Added", "Loads"]}>
  ## ¿Qué hay de nuevo?

  Hemos añadido un endpoint `PATCH /p/v1.0/loads/{loadNumber}` a la API pública. Los partners que operan un sistema externo de registro (por ejemplo, AS400) ahora pueden escribir su identificador generado de vuelta en una carga de Alvys como el **Order Number (Shipment ID)** — de forma programática, sin humanos en el ciclo.

  El endpoint es una **actualización parcial**: solo se modifican los campos que envías, dejando todo lo demás intacto. Está diseñado para que se puedan añadir más campos escribibles de carga en el futuro sin romper el contrato. En esta primera iteración, `orderNumber` es el único campo escribible.

  ## ¿Qué cambió?

  Anteriormente, el Order Number de una carga solo podía establecerse en la UI — no había una ruta pública de escritura. Ahora puedes actualizarlo directamente:

  ```bash theme={null}
  curl --location --request PATCH 'https://integrations.alvys.com/api/p/v1.0/loads/3039979' \
  --header 'Authorization: Bearer YOUR_ACCESS_TOKEN' \
  --header 'Content-Type: application/json' \
  --header 'If-Match: "8DBAC1F2E3..."' \
   --data-raw '{
    "orderNumber": "2026-00471"
  }'
  ```

  Una llamada exitosa devuelve `200 OK` con la representación de la carga actualizada y un nuevo `ETag`.

  ## Cómo prevenir sobrescrituras accidentales

  Para ayudar a prevenir que una actualización sobrescriba accidentalmente otra, este endpoint requiere la última versión del registro al realizar cambios.

  Cuando recuperas o actualizas un registro, la respuesta incluye un `ETag`. Envía ese valor en el encabezado de solicitud `If-Match` al realizar tu próxima actualización.

  | Escenario                                       | Respuesta                   |
  | ----------------------------------------------- | --------------------------- |
  | Falta el encabezado `If-Match`                  | `428 Precondition Required` |
  | El registro cambió desde tu última recuperación | `412 Precondition Failed`   |
  | La actualización tiene éxito                    | `200 OK`                    |

  Si recibes `412 Precondition Failed`, recupera el registro nuevamente para obtener el último `ETag` y luego reintenta la actualización.

  Después de una actualización exitosa, el nuevo `ETag` se devuelve tanto en el cuerpo de la respuesta como en el encabezado de respuesta `ETag`, por lo que puedes usarlo para la próxima actualización sin hacer otra solicitud `GET`.

  ## Validación e historial

  * Un Order Number en blanco o vacío se rechaza con `400 Bad Request` — la misma regla que la actualización interna del Order Number.
  * Cada cambio se escribe en el historial de la carga (la misma pista de auditoría que la ruta de la UI).
  * Las cargas originadas por EDI se rechazan. El Order Number en una carga EDI está bloqueado al valor recibido en el tender entrante y no se puede cambiar a través de este endpoint.

  ## Endpoints afectados

  `PATCH /p/v1.0/loads/{loadNumber}` es nuevo y actualiza el Order Number de una carga.

  No se cambiaron formas de solicitud o respuesta para los endpoints existentes. Esta actualización es totalmente retrocompatible.

  ## Códigos de respuesta

  | Código                      | Significado                                                             |
  | --------------------------- | ----------------------------------------------------------------------- |
  | `200 OK`                    | Order Number actualizado; carga actualizada devuelta con un nuevo ETag. |
  | `400 Bad Request`           | Solicitud inválida (por ejemplo, Order Number en blanco).               |
  | `401 / 403`                 | Falla de autenticación o permisos.                                      |
  | `404 Not Found`             | Carga no encontrada dentro de la empresa del llamador.                  |
  | `409 Conflict`              | Estado conflictivo.                                                     |
  | `412 Precondition Failed`   | ETag obsoleto.                                                          |
  | `428 Precondition Required` | Falta el encabezado `If-Match`.                                         |

  <br />
</Update>

<Update label="June 3, 2026" description="Servidor MCP remoto para Alvys Public API" tags={["Added", "MCP"]}>
  **Fecha de lanzamiento:** 3 de junio de 2026 (servidor), 18 de junio de 2026 (prompts y herramientas de escritura), 3 de julio de 2026 (inicio de sesión de usuario)

  ### ¿Qué hay de nuevo?

  Alvys ahora ofrece un servidor remoto **Model Context Protocol (MCP)** que expone Public API a agentes de IA — Claude, Cursor y sus propios agentes personalizados. En lugar de cablear llamadas HTTP a mano, un agente se conecta a un endpoint gobernado y descubre las herramientas Alvys automáticamente.

  ### ¿Qué cambió?

  Anteriormente, integrar un agente de IA con Alvys significaba mantener un token Public API sin procesar y llamar endpoints REST directamente.

  Ahora, los agentes se conectan al servidor MCP de Alvys y obtienen:

  * **Herramientas de lectura** en entidades principales — cargas, viajes, transportistas, clientes, conductores, camiones, tráilers, facturas, deducciones, transacciones de combustible, tenders, historial de visibilidad y documentos.
  * **Herramientas de escritura** (opcional) — crear/aceptar/rechazar tenders, registrar pagos de transportista y cliente, registrar financiación, asignar y despachar viajes, actualizar estado de transportista, subir documentos, registrar llegadas/salidas de paradas y actualizar citas de paradas.
  * **Prompts curados (v1)** — flujos guiados de varios pasos como `find_and_cover_load`, `dispatch_driver`, `carrier_onboarding`, `settlement_reconciliation` y `track_shipment`.

  ### Autenticación

  Dos formas de conectar:

  * **Máquina a máquina** — tokens client-credentials de Auth0, igual que Public API.
  * **Inicio de sesión de usuario** — OAuth 2.1 con PKCE según la especificación MCP, incluido descubrimiento de recurso protegido (RFC 9728) e indicadores de recurso (RFC 8707), para que clientes interactivos como Claude puedan iniciar sesión como usuario.

  ### Gobernanza y seguridad

  * El aislamiento por tenant se aplica desde el token — nunca desde el cuerpo de la solicitud.
  * Cada herramienta se clasifica **Read / Write / Destructive** con compuertas en tiempo de ejecución; las herramientas de escritura están deshabilitadas salvo que se habiliten explícitamente.
  * Cada herramienta requiere un permiso API granular coincidente (por ejemplo `tender:read`, `invoice:update`).
  * Todas las llamadas tienen límite de velocidad, tope de tamaño y registro de auditoría.

  ### ¿Por qué?

  Los agentes de IA se están convirtiendo en una forma de primera clase de operar un TMS. El servidor MCP les da una superficie descubrible, auditada y aislada por tenant — un único punto de control con autorización a nivel de herramienta en lugar de tokens API sin procesar repartidos entre agentes.
</Update>

<Update label="May 29, 2026" description="API pública: endpoints de escritura de cliente (crear, actualizar, eliminar)" tags={["Added", "Customers"]}>
  La API pública ahora admite **escrituras** en el recurso `Customer`. Los partners pueden crear nuevos clientes, actualizar los existentes y hacer soft-delete directamente a través de la API — se acabó el techo de solo lectura.

  Esta versión es **puramente aditiva**. Las lecturas existentes con `GET` y `POST /api/p/v1.0/customers/search` no cambian.

  ## Qué hay de nuevo

  | Endpoint                            | Acción                               | Devuelve                        | Permiso           |
  | ----------------------------------- | ------------------------------------ | ------------------------------- | ----------------- |
  | `POST /api/p/v1.0/customers`        | Crear                                | `201` + `CustomerWriteResponse` | `customer:create` |
  | `PATCH /api/p/v1.0/customers/{id}`  | Actualizar (parcial, merge RFC 7396) | `200` + `CustomerWriteResponse` | `customer:update` |
  | `DELETE /api/p/v1.0/customers/{id}` | Soft-delete                          | `204`                           | `customer:delete` |

  Se aplica a ambos tipos de empresa de negocio: `Customer` y `Broker/3PL`.

  ## Por qué importa

  * **Sincronización de CRM en tiempo real** — empuja los registros de clientes directamente a Alvys desde tu TMS, ERP o CRM en lugar de ingresarlos a mano.
  * **Ediciones seguras ante conflictos** — la concurrencia optimista con `ETag` / `If-Match` significa que dos ediciones simultáneas nunca se sobrescriben silenciosamente.

  ## Crear

  ```http theme={null}
  POST /api/p/v1.0/customers
  Authorization: Bearer <token with customer:create>
  Content-Type: application/json

  {
    "Name": "Acme Logistics",
    "Type": "Customer",
    "CompanyNumber": "ACME-1",
    "Status": "Active",
    "BillingAddress": { "Street": "1 Main", "City": "City", "State": "NY", "Zip": "10001" },
    "Email": ["billing@acme.example"],
    "Phone": ["555-1234"]
  }
  ```

  Devuelve `201 Created` con un cuerpo `Response`. El `ETag` se devuelve tanto en el cuerpo como en el encabezado de respuesta. `Name` y `Type` son obligatorios al crear; `Type` debe ser `Customer` o `Broker/3PL`.

  ## Actualizar (parcial)

  ```http theme={null}
  PATCH /api/p/v1.0/customers/{id}
  Authorization: Bearer <token with customer:update>
  If-Match: "etag-from-prior-read"

  { "Status": "Inactive" }
  ```

  Devuelve `200 OK`. `PATCH` es una actualización parcial real (RFC 7396 JSON Merge Patch) — omite cualquier campo para dejarlo sin cambios.

  ## Eliminar

  ```http theme={null}
  DELETE /api/p/v1.0/customers/{id}
  Authorization: Bearer <token with customer:delete>
  If-Match: "etag-from-prior-read"
  ```

  Devuelve `204 No Content`. El registro pasa a `Status: Inactive` (soft-delete) y su `CompanyNumber` permanece reservado para prevenir su reutilización.

  ## Campos escribibles soportados

  Los siguientes campos se pueden crear o actualizar a través de los endpoints de escritura de Customer:

  `Name`, `Type`, `CompanyNumber`, `Status`, `BillingAddress`, `Email`, `Phone`, `Fax`, `ExternalId`.

  Todos los demás campos son de solo lectura o gestionados por Alvys, incluyendo `SalesAgentId`, `Contacts`, `Notes`, `InvoicingInformation`, `Id`, `DateCreated` y `DateModified`.

  Los campos no soportados o de solo lectura incluidos en el cuerpo de la solicitud se ignoran.

  ## Validación de campos

  | Campo           | Validación                                                           |
  | --------------- | -------------------------------------------------------------------- |
  | `Name`          | Obligatorio. No puede estar en blanco. Máximo 200 caracteres.        |
  | `CompanyNumber` | Máximo 32 caracteres. No se aceptan valores de marcador de posición. |
  | `ExternalId`    | Máximo 100 caracteres.                                               |
  | `Status`        | Debe ser `Active` o `Inactive`.                                      |

  ## Comportamiento de solicitud

  `PATCH` y `DELETE` requieren el encabezado `If-Match`.

  Si falta `If-Match`, la API devuelve `428 Precondition Required`. Si el `ETag` está desactualizado, la API devuelve `412 Precondition Failed`. Recupera el cliente de nuevo para obtener el último `ETag` y luego reintenta.

  Un `CompanyNumber`, `ExternalId` o `Name` + código postal de facturación duplicados devuelven `409 Conflict`. La respuesta identifica el campo en conflicto y el `customerId` existente.

  Si las escrituras de cliente están temporalmente no disponibles, la API devuelve `503 Service Unavailable` con `Retry-After: 3600` y el tipo de problema `EndpointDisabled`. Los endpoints de lectura de cliente permanecen disponibles.

  ## Respuestas de escritura y lectura

  Las solicitudes `POST` y `PATCH` exitosas devuelven `CustomerWriteResponse`.

  La respuesta de escritura incluye:

  `Id`, `ETag`, `Name`, `CompanyNumber`, `Type`, `Status`, `BillingAddress`, `Email`, `Phone`, `Fax`, `DateCreated`, `DateModified`, `InvoicingInformation`, `ExternalId`.

  Para las respuestas de escritura, el `ETag` se devuelve tanto en el cuerpo como en el encabezado de respuesta.

  Los endpoints existentes `GET` y de búsqueda no cambian. Continúan devolviendo `CustomerResponse`, con `Status` como `Active` o `Inactive` y `ETag` solo en el encabezado de respuesta.

  ## Acceso

  Usa tus Client Credentials existentes y añade los scopes que necesites:

  * `customer:read` — `GET` / `search`&#x20;
  * `customer:create` — `POST`
  * `customer:update` — `PATCH`
  * `customer:delete` — `DELETE`

  No se requiere una nueva credencial o cliente OAuth. Los scopes se conceden por Client Credentials en [API management](https://app.alvys.com/#/manage/public-api).

  ## Preguntas frecuentes

  **¿Necesito una nueva credencial o cliente OAuth?**<br />No. Tus Client Credentials existentes funcionan — solo añade los scopes `customer:create` / `customer:update` / `customer:delete` que necesites. `customer:read` no cambia.

  **¿Cómo obtengo el **`ETag`** para una actualización o eliminación?**
  Se devuelve en el encabezado de respuesta de cualquier `GET`, `POST` o `PATCH`, y adicionalmente en el cuerpo de `POST` / `PATCH`. Úsalo como `If-Match` en tu próxima mutación. Ante un `412`, vuelve a hacer `GET` para obtener el valor actualizado.

  **¿Qué pasa si dos llamadores actualizan el mismo cliente al mismo tiempo?**
  El primer `PATCH` gana (`200`); el segundo ve un `If-Match` obsoleto y obtiene `412`. Vuelve a hacer `GET`, reaplica, reintenta. Sin sobrescritura silenciosa.

  **¿Realmente **`DELETE`** elimina el registro?**
  No — es un soft-delete. `Status` pasa a `Inactive` y el `CompanyNumber` permanece reservado (un `POST` duplicado con ese número devuelve `409`). Para restaurar, haz `PATCH` con `{ "Status": "Active" }`.

  **¿Qué pasa si envío un campo no soportado como **`Notes`** en el cuerpo?**
  Se ignora silenciosamente. Solo se aplican los campos escribibles listados arriba.

  **¿Este cambio modifica la forma de la respuesta de **`GET`** o de búsqueda existente?**
  No. La superficie de lectura no cambia; esta versión es puramente aditiva.

  **¿Cuándo veo **`404`** vs **`412`**?**
  `404` = el id no existe en tu tenant (los ids en otro tenant también devuelven `404`). `412` = el id existe en tu tenant pero tu `If-Match` está obsoleto — vuelve a hacer `GET` para obtener el `ETag` actual.
</Update>

<Update label="May 22, 2026" description="Eventos de webhook para actualizaciones generales de cargas y viajes" tags={["Added", "Webhooks", "Trips"]}>
  ## ¿Qué hay de nuevo?

  Hemos añadido dos nuevos tipos de eventos de webhook a la API pública: `load.changed` y `trip.changed`. Siempre que se actualiza un campo operativo (como tarifas, citas, paradas o asignaciones de transportistas) en una carga o viaje, Alvys ahora envía un webhook en tiempo real a cada suscripción activa que seleccionó esos eventos.

  ## ¿Qué cambió?

  Anteriormente, detectar actualizaciones a nivel de carga y viaje requería sondear `GET /loads` y `GET /trips` de forma programada. Ahora, los siguientes tipos de eventos están disponibles junto a los eventos existentes y se pueden seleccionar al crear o editar una suscripción de webhook:

  * `load.changed`
  * `trip.changed`

  La lista completa también la devuelve: `GET /p/v1.0/webhooks/event-types`

  ## Envoltorio del evento

  Todas las entregas de webhook comparten el envoltorio estándar de Alvys. Los nuevos tipos de evento lo reutilizan con un sufijo de ID específico para idempotencia:

  ```jsonc theme={null}
  {
    "id": "93d579d3-6b50-4f97-8764-1ad07c3efd97-d900dc51-...-0",
    "type": "load.changed",
    "timestamp": "2026-05-22T09:19:52.652Z",
    "version": "v1",
    "data": { /* event-specific payload - see below */ }
    // Other envelope fields are omitted from this example for brevity.
  }

  ```

  El `id` del envoltorio es único por evento y debe usarse como clave de idempotencia en el lado del consumidor. *Nota: Los cambios generales terminan en sufijo *`-0`*, mientras que los cambios de estado terminan en *`-1`*.*

  ## load.changed

  Se dispara cuando se crea o actualiza un documento de carga. El payload lleva un snapshot completo de la carga de la API pública - la misma forma devuelta por `GET /p/v1.0/loads/{loadNumber}`.

  ```jsonc theme={null}
  {
    "load": {
      "id": "93d579d3-6b50-4f97-8764-1ad07c3efd97",
      "loadNumber": "3039979",
      "orderNumber": "ABC-12-007",
      "status": "Open",
      "loadType": "Revenue",
      "customerRate": {
        "amount": 1749.06,
        "currency": 840
      }
      // Full Public-API load object - same fields as GET /p/v1.0/loads/{loadNumber}.
      // Other fields (stops, charges, references, etc.) omitted here for brevity.
    }
  }

  ```

  ## trip.changed

  Se dispara cuando se crea o actualiza un documento de viaje. El payload lleva un snapshot completo del viaje de la API pública - la misma forma devuelta por `GET /p/v1.0/trips/{tripId}`.

  ```jsonc theme={null}
  {
    "trip": {
      "id": "dd5ba174abe845568f5e5c2a850db8ca",
      "tripNumber": "3039979",
      "status": "Open",
      "loadNumber": "3039979",
      "orderNumber": "ABC-12-007",
      "tripValue": {
        "amount": 1599.06,
        "currency": 840
      }
      // Full Public-API trip object - same fields as GET /p/v1.0/trips/{tripId}.
      // Other fields (driver, truck, stops, accessorials, etc.) omitted here for brevity.
    }
  }

  ```

  ## Endpoints afectados

  * `GET /p/v1.0/webhooks/event-types` ahora devuelve `load.changed` y `trip.changed`.
  * `POST /p/v1.0/webhooks` / `PUT /p/v1.0/webhooks/{id}` aceptan los nuevos valores de tipo de evento en el array `eventTypes`.

  No se cambiaron formas de solicitud/respuesta para los endpoints existentes. Esta actualización es totalmente retrocompatible.

  ## ¿Por qué?

  Estos eventos permiten a los partners de API e integraciones:

  * Reaccionar a los cambios operativos de cargas y viajes en tiempo real, sin sondeo.
  * Reducir el volumen total de llamadas a la API en `/loads` y `/trips`.
  * Impulsar automatizaciones descendentes (factoring, seguimiento, facturación) en el momento en que cambia un estado operativo.
  * Mantener consistentes las pistas de auditoría a través de la UI existente de Delivery Logs de webhook.&#x20;

  <br />
</Update>

<Update label="May 13, 2026" description="Webhooks de documentos por entidad para cargas, viajes, conductores, transportistas, camiones y remolques" tags={["Added", "Webhooks", "Carriers"]}>
  ## ¿Qué hay de nuevo?

  Doce nuevos tipos de eventos de webhook ya están disponibles en la API pública: dos para cada entidad padre que expone documentos a través de la API. Cada vez que se sube o elimina un documento en Alvys, la plataforma emite un webhook a cada suscripción activa que haya seleccionado el evento correspondiente.

  | Evento                      | Se dispara cuando                                       |
  | --------------------------- | ------------------------------------------------------- |
  | `load.document.uploaded`    | Se adjunta un nuevo documento a una carga               |
  | `load.document.deleted`     | Se elimina lógicamente un documento de una carga        |
  | `trip.document.uploaded`    | Se adjunta un nuevo documento a un viaje                |
  | `trip.document.deleted`     | Se elimina lógicamente un documento de un viaje         |
  | `driver.document.uploaded`  | Se adjunta un nuevo documento a un conductor            |
  | `driver.document.deleted`   | Se elimina lógicamente un documento de un conductor     |
  | `carrier.document.uploaded` | Se adjunta un nuevo documento a un transportista        |
  | `carrier.document.deleted`  | Se elimina lógicamente un documento de un transportista |
  | `truck.document.uploaded`   | Se adjunta un nuevo documento a un camión               |
  | `truck.document.deleted`    | Se elimina lógicamente un documento de un camión        |
  | `trailer.document.uploaded` | Se adjunta un nuevo documento a un remolque             |
  | `trailer.document.deleted`  | Se elimina lógicamente un documento de un remolque      |

  Los eventos se disparan independientemente del origen de la escritura: subidas desde la interfaz, subidas desde la API pública, subidas desde la app móvil, ingesta de documentos EDI o integraciones de terceros producen las mismas entregas.

  Cada evento `*.document.uploaded` incluye una URL de descarga prefirmada de corta duración (TTL ≤ 15 minutos) para que los partners puedan obtener el archivo directamente desde el almacenamiento de blobs sin una llamada adicional a la API.

  ## ¿Qué cambió?

  ### Suscripción

  En **Settings → API → Webhooks → Create / Edit subscription**, seleccione cualquier combinación de los nuevos tipos de eventos. La lista completa también se devuelve mediante `GET /p/v1.0/webhooks/event-types` para configuración programática.

  ### Envelope (estructura general)

  Todas las entregas de webhooks de documentos comparten el envelope estándar utilizado por `tender.*`, `load.status.changed` y `trip.status.changed`. `id` es la clave de idempotencia determinística (`{documentId}-{etag}`); `etag` también se expone como su propio campo de nivel superior del envelope para que los consumidores puedan detectar repeticiones fuera de orden para el mismo `documentId`.

  ### Payload de `*.document.uploaded` (estructura general)

  Muestra real de producción (`trip.document.uploaded`):

  ```json theme={null}
  {
    "id": "00000000-0000-0000-0000-000000000000-00000000-0000-0000-0000-000000000000",
    "type": "trip.document.uploaded",
    "timestamp": "2026-05-13T09:16:30.9797738+00:00",
    "version": "v1",
    "etag": "00000000-0000-0000-0000-000000000000",
    "data": {
      "tripId": "00000000000000000000000000000000",
      "document": {
        "id": "00000000-0000-0000-0000-000000000000",
        "attachmentPath": "bol.pdf",
        "attachmentType": "Bill of Lading",
        "attachmentSize": 10000,
        "uploadedAt": "2026-05-13T09:16:30.9797738+00:00",
        "parentId": "1000000",
        "parentType": "Trip",
        "uploadedBy": "00000000000000000000000000000000",
        "downloadUrl": "{url}",
        "expiresAt": "2026-05-13T09:26:35.3227049+00:00"
      }
    }
  }
  ```

  * `data.tripId` es el **GUID del viaje** (el identificador público natural devuelto por `GET /p/v1.0/trips/{tripId}`).
  * `data.document.parentId` en un documento de viaje es el **número de carga** (`"1000000"`), coincidiendo con la forma en que los documentos de viaje se almacenan internamente y se devuelven por `GET /loads/{loadNumber}/documents`.
  * `attachmentType` es un tipo de documento de Alvys **legible por humanos** (por ejemplo, `"Bill of Lading"`, `"Proof of Delivery"`, `"Rate Confirmation"`), el mismo valor devuelto por los endpoints de la API pública de documentos.
  * `uploadedBy` es el **id de usuario** (GUID) de quien realizó la subida.

  La misma forma aplica a los otros cinco tipos de entidad padre: `data` siempre contiene el identificador público natural del padre (`loadNumber`, `tripId`, `driverId`, `carrierId`, `truckId` o `trailerId`) más un bloque `document`. Por ejemplo, `driver.document.uploaded` reemplaza `tripId` por `driverId`; el bloque `document` es idéntico.

  ### Payload de `*.document.deleted` (estructura general)

  ```json theme={null}
  // load.document.deleted
  {
    "id": "00000000-0000-0000-0000-000000000000-00000000-0000-0000-0000-000000000000",
    "type": "load.document.deleted",
    "timestamp": "2026-05-13T16:05:22.118+00:00",
    "version": "v1",
    "etag": "00000000-0000-0000-0000-000000000000",
    "data": {
      "loadNumber": "1000000",
      "document": {
        "id": "00000000-0000-0000-0000-000000000000",
        "attachmentPath": "bol.pdf",
        "attachmentType": "Bill of Lading",
        "attachmentSize": 10000,
        "uploadedAt": "2026-05-13T09:16:30.9797738+00:00",
        "uploadedBy": "00000000000000000000000000000000",
        "parentId": "1000000",
        "parentType": "Load"
      }
    }
  }
  ```

  `downloadUrl` y `expiresAt` se omiten en los eventos de eliminación: el documento se considera lógicamente inexistente, por lo que los consumidores no deben descargar bytes.

  ### Notas de comportamiento

  * Un evento se dispara **solo cuando un documento se crea o se elimina lógicamente**: renombrar, cambiar de tipo y otras ediciones solo de metadatos no generan entregas.
  * El `downloadUrl` prefirmado es de corta duración (≤ 15 minutos). Descargue el archivo con prontitud, o recurra a `GET /p/v1.0/{parent}/{parentId}/documents/{documentId}` si expira.

  ## Endpoints afectados

  ### Gestión de suscripciones de webhook

  Estos endpoints existentes ahora aceptan los doce nuevos tipos de eventos en su arreglo `eventTypes`:

  * `GET /p/v1.0/webhooks/event-types`: devuelve el catálogo completo incluyendo los nuevos tipos de eventos de documento.
  * `POST /p/v1.0/webhooks`: crea una suscripción que selecciona cualquier combinación de los nuevos eventos.
  * `PUT /p/v1.0/webhooks/{id}`: actualiza una suscripción existente para agregar o eliminar eventos de documento.
  * `GET /p/v1.0/webhooks/{id}`: inspecciona qué eventos está seleccionando una suscripción.
  * `GET /p/v1.0/webhooks/{id}/deliveries`: el historial de entregas para los nuevos eventos fluye a través de la misma superficie de logs que `tender.*` y `*.status.changed`.

  ### Endpoints de documento que impulsan los eventos

  Cualquier escritura a los siguientes subrecursos de documento disparará el webhook correspondiente para los suscriptores activos. **No ha cambiado la forma de la solicitud ni de la respuesta en estos endpoints**: se listan aquí para que pueda correlacionar qué acciones de la API producen qué eventos.

  | Endpoint                                                     | Dispara                     |
  | ------------------------------------------------------------ | --------------------------- |
  | `POST /p/v1.0/loads/{loadNumber}/documents`                  | `load.document.uploaded`    |
  | `DELETE /p/v1.0/loads/{loadNumber}/documents/{documentId}`   | `load.document.deleted`     |
  | `POST /p/v1.0/trips/{tripId}/documents`                      | `trip.document.uploaded`    |
  | `DELETE /p/v1.0/trips/{tripId}/documents/{documentId}`       | `trip.document.deleted`     |
  | `POST /p/v1.0/drivers/{driverId}/documents`                  | `driver.document.uploaded`  |
  | `DELETE /p/v1.0/drivers/{driverId}/documents/{documentId}`   | `driver.document.deleted`   |
  | `POST /p/v1.0/carriers/{carrierId}/documents`                | `carrier.document.uploaded` |
  | `DELETE /p/v1.0/carriers/{carrierId}/documents/{documentId}` | `carrier.document.deleted`  |
  | `POST /p/v1.0/trucks/{truckId}/documents`                    | `truck.document.uploaded`   |
  | `DELETE /p/v1.0/trucks/{truckId}/documents/{documentId}`     | `truck.document.deleted`    |
  | `POST /p/v1.0/trailers/{trailerId}/documents`                | `trailer.document.uploaded` |
  | `DELETE /p/v1.0/trailers/{trailerId}/documents/{documentId}` | `trailer.document.deleted`  |

  Las subidas desde la interfaz, subidas desde la app móvil, ingesta EDI e integraciones de terceros también producen los mismos eventos aunque no pasen por los endpoints de la API pública mencionados arriba.

  ### Obtención de reserva (si un `downloadUrl` expira)

  Si el `downloadUrl` prefirmado de 15 minutos expira antes de que pueda obtener el archivo, recupere el documento a través del endpoint autenticado estándar:

  ```
  GET /p/v1.0/{parent}/{parentId}/documents/{documentId}
  ```

  ## ¿Por qué?

  Hasta ahora, para obtener documentos recién subidos era necesario sondear el subrecurso de documento en cada padre: `/loads/{loadNumber}/documents`, `/drivers/{driverId}/documents` y cuatro más. Con estos eventos en su lugar:

  * ⚡ **Automatización de documentos en tiempo real**: la automatización de facturación basada en POD, el factoring, la gestión documental y la validación de facturas EDI 210 ya no dependen de un bucle de sondeo.
  * 🔁 **Menor carga en la API**: elimina el tráfico de sondeo contra seis endpoints padre diferentes.
  * 🎯 **Suscríbase de forma acotada**: los eventos están delimitados por entidad (`load.*` vs `driver.*` vs `carrier.*` …). Una integración de factoring que solo se interesa por documentos del lado de la carga no recibirá actualizaciones de tarjetas médicas de conductores.
  * 🧾 **Rastro de auditoría incorporado**: cada intento de entrega se registra y es visible en la página de detalles del Webhook.
  * 🔗 **Descarga directa**: cada evento `*.uploaded` lleva una URL de descarga prefirmada.

  ## ¿Quién tiene acceso?

  Todos los consumidores de la API pública con una suscripción de webhook activa que seleccione cualquiera de los nuevos tipos de eventos. La gestión de suscripciones requiere el rol Partner Admin / Admin / Support en **Settings → API → Webhooks**.

  ## Preguntas Frecuentes (FAQ)

  **P: ¿Necesito una nueva credencial o alcance para recibir estos eventos?** R: No. Las suscripciones de webhook existentes pueden habilitarlos seleccionando los nuevos tipos de eventos.

  **P: ¿El `downloadUrl` es reutilizable?** R: Es un SAS prefirmado de Azure Blob de un solo uso y corta duración, válido hasta por 15 minutos desde su emisión. Si expira, recupere el documento a través del endpoint estándar de la API pública en su lugar.

  **P: ¿Los eventos están ordenados?** R: Las entregas están ordenadas por documento en la medida de lo posible. Los consumidores deben ser **idempotentes** y utilizar el `id` del envelope (`{documentId}-{_etag}`) como clave de idempotencia.

  **P: ¿Puedo ver el historial de entregas de estos eventos?** R: Sí: la barra lateral **Logs** existente en la página de detalles del webhook muestra cada intento de entrega para estos tipos de eventos, con el mismo filtrado, paginación y exportación CSV/JSON que `tender.*` y los eventos de cambio de estado.

  **P: ¿Están disponibles los eventos de actualización / renombrado de documentos?** R: No en esta versión. Hoy emitimos solo en la subida y la eliminación lógica. Los eventos de actualización podrían agregarse más adelante como `*.document.updated` si hay demanda por parte de los clientes.
</Update>

<Update label="May 4, 2026" description="Eventos de webhook para actualizaciones de estado de cargas y viajes" tags={["Added", "Webhooks", "Trips"]}>
  ### ¿Qué hay de nuevo?

  Hemos añadido dos nuevos tipos de eventos de webhook a la API pública: **`load.status.changed`** y **`trip.status.changed`**. Cada vez que una carga o un viaje pasa de un estado a otro (por ejemplo, `Covered → Dispatched` o `Dispatched → InTransit`), Alvys ahora envía un webhook en tiempo real a cada suscripción activa que haya seleccionado esos eventos.

  ### ¿Qué cambió?

  Anteriormente, la API pública exponía webhooks solo para eventos del ciclo de vida del tender. Detectar transiciones de estado a nivel de carga y viaje requería sondear `GET /loads` y `GET /trips` de forma programada.

  Ahora, los siguientes tipos de eventos están disponibles junto con los eventos existentes de `tender.*` y pueden seleccionarse al crear o editar una suscripción de webhook:

  ```
  load.status.changed
  trip.status.changed
  ```

  La lista completa también se devuelve mediante:

  ```
  GET /p/v1.0/webhooks/event-types
  ```

  ### Envelope del evento

  Todas las entregas de webhooks comparten el envelope estándar de Alvys. Los nuevos tipos de eventos lo reutilizan sin cambios:

  ```jsonc theme={null}
  {
    "id": "…",
    "type": "load.status.changed",
    "timestamp": "2026-05-04T14:32:11.482Z",
    "version": "1",
    "data": { /* payload específico del evento — ver abajo */ }
    // Otros campos del envelope se omiten en este ejemplo por brevedad.
  }
  ```

  El `id` del envelope es único por evento y debe utilizarse como **clave de idempotencia** en el lado del consumidor.

  ### `load.status.changed`

  Se dispara cuando una carga pasa de un estado a otro. El payload lleva el delta de estado anterior + actual y una instantánea completa de la carga de la API pública, con la misma forma devuelta por `GET /p/v1.0/loads/{loadNumber}`.

  ```jsonc theme={null}
  {
    "previousStatus": "Covered",
    "status": "Dispatched",
    "load": {
      "id": "…",
      "loadNumber": "1006321",
      "status": "Dispatched"
      // Objeto completo de carga de la API pública — mismos campos que GET /p/v1.0/loads/{loadNumber}.
      // Otros campos (customer, stops, charges, references, etc.) se omiten aquí por brevedad.
    }
  }
  ```

  ### `trip.status.changed`

  Se dispara cuando un viaje pasa de un estado a otro. El payload lleva el delta de estado anterior + actual y una instantánea completa del viaje de la API pública, con la misma forma devuelta por `GET /p/v1.0/trips/{tripId}`.

  ```jsonc theme={null}
  {
    "previousStatus": "Dispatched",
    "status": "InTransit",
    "trip": {
      "id": "…",
      "tripNumber": "T-1006321-1",
      "status": "InTransit"
      // Objeto completo de viaje de la API pública — mismos campos que GET /p/v1.0/trips/{tripId}.
      // Otros campos (driver, truck, stops, accessorials, etc.) se omiten aquí por brevedad.
    }
  }
  ```

  ### Comportamiento

  * Los eventos se emiten **solo en transiciones reales**, cuando `status` difiere de `previousStatus`. Las escrituras sin efecto no generan entregas.
  * `load` / `trip` pueden ser `null` si la lectura de la instantánea falla o si el payload excedió el límite de tamaño y fue eliminado. Los campos `previousStatus` y `status` siempre están presentes para que los consumidores puedan reaccionar a la transición y volver a consultar mediante `GET /loads/{id}` o `GET /trips/{id}` si es necesario.
  * Las entregas están firmadas (`X-Alvys-Signature`), se reintentan con retroceso exponencial y las suscripciones se desactivan automáticamente tras fallos sostenidos, de forma idéntica a los eventos `tender.*` existentes.

  ### Endpoints afectados

  * `GET /p/v1.0/webhooks/event-types`: ahora devuelve `load.status.changed` y `trip.status.changed`
  * `POST /p/v1.0/webhooks` / `PUT /p/v1.0/webhooks/{id}`: aceptan los nuevos valores de tipo de evento en el arreglo `eventTypes`

  No se cambiaron las formas de solicitud/respuesta para los endpoints existentes. Esta actualización es totalmente compatible con versiones anteriores.

  ### ¿Por qué?

  Estos eventos permiten a los partners e integraciones de la API:

  * Reaccionar a cambios de estado de cargas y viajes en tiempo real, sin sondeo
  * Reducir el volumen general de llamadas a la API en `/loads` y `/trips`
  * Impulsar automatizaciones descendentes (factoring, seguimiento, facturación) en el momento en que cambia un estado operativo
  * Mantener los rastros de auditoría consistentes a través de la interfaz existente de Logs de entrega de webhooks

  Esta actualización amplía la superficie de webhooks de la API pública con cobertura del ciclo de vida operativo, preservando el contrato existente del envelope de eventos.
</Update>

<Update label="April 22, 2026" description="Mejoras en pagos a transportistas y de clientes en la API pública" tags={["Added", "Carriers", "Customers"]}>
  ### ¿Qué hay de nuevo?

  Hemos introducido nuevas capacidades de la API pública para **pagos a transportistas**, **pagos de clientes** y **transacciones de financiamiento**. Estas incorporaciones facilitan que las plataformas externas de pago, los proveedores de factoring y los sistemas financieros sincronicen la actividad financiera directamente con Alvys.

  ### ¿Qué cambió?

  Anteriormente, la API pública no proporcionaba endpoints dedicados para registrar estas transacciones financieras.

  Ahora, la API incluye los siguientes nuevos endpoints:

  ```http id="k6t1i1" theme={null}
  POST /p/v1.0/invoices/carrier-payments
  POST /p/v1.0/invoices/customer-payments
  POST /p/v1.0/invoices/financing
  ```

  ### Pagos a transportistas

  Registra un pago realizado a un transportista por un viaje.

  Ejemplo:

  ```json id="nh6qzc" theme={null}
  {
    "tripId": "string",
    "amount": {
      "value": 1000.00,
      "currency": "USD"
    }
  }
  ```

  Actualiza campos de pago del viaje como `carrierPaidAt`.

  ### Pagos de clientes

  Registra un pago recibido de un cliente por una carga.

  Ejemplo:

  ```json id="g5vqlv" theme={null}
  {
    "loadId": "string",
    "amount": {
      "value": 2500.00,
      "currency": "USD"
    }
  }
  ```

  Actualiza los detalles de pago de la carga como:

  * `paidAt`
  * `totalPaid`
  * `payments[]`

  ### Financiamiento

  Registra actividad de financiamiento como montos de reserva o de escrow para una carga.

  Ejemplo:

  ```json id="gblx2d" theme={null}
  {
    "loadId": "string",
    "reserveAmount": {
      "value": 500.00,
      "currency": "USD"
    },
    "escrowAmount": {
      "value": 200.00,
      "currency": "USD"
    }
  }
  ```

  ### Endpoints afectados:

  * `POST /p/v1.0/invoices/carrier-payments`
  * `POST /p/v1.0/invoices/customer-payments`
  * `POST /p/v1.0/invoices/financing`

  ### ¿Por qué?

  Estas mejoras proporcionan:

  * Integración más rápida con plataformas de pago y finanzas
  * Mejor automatización para cuentas por cobrar y por pagar
  * Soporte para flujos de trabajo de factoring y escrow
  * Menor entrada manual de transacciones financieras
  * Mejor visibilidad contable a través de cargas y viajes

  Esta actualización amplía las capacidades de integración financiera de la API pública manteniendo la compatibilidad con versiones anteriores.
</Update>

<Update label="April 17, 2026" description="La búsqueda de viajes devuelve tombstones para viajes eliminados" tags={["Improved", "Trips"]}>
  ### ¿Qué hay de nuevo?

  Hemos actualizado el comportamiento de **Trip Search** para **viajes invisibles creados por flujos de split, re-split y unsplit** cuando se usa `includeDeleted: true`. Esto mejora la fiabilidad de la sincronización para integraciones que sondean viajes usando `updatedSince` o `updatedAtRange`.

  ### ¿Qué cambió?

  El comportamiento predeterminado no cambia:

  * cuando se omite `includeDeleted`, Trip Search devuelve únicamente viajes visibles y no eliminados
  * cuando `includeDeleted=false`, Trip Search también devuelve únicamente viajes visibles y no eliminados

  El comportamiento modificado aplica solo cuando `includeDeleted=true`.

  Anteriormente, cuando se dividía una carga, los viajes reemplazados u ocultos podían desaparecer silenciosamente de los resultados de la API, incluso cuando `includeDeleted=true`. Esto dificultaba a las integraciones detectar transiciones del ciclo de vida y podía dejar registros obsoletos en los sistemas descendentes.

  Ahora, cuando `includeDeleted=true`, Trip Search devuelve los registros de viaje invisibles como tombstones, mostrándolos con `isDeleted: true`. Esto incluye:

  * viajes base reemplazados
  * legs hijos ocultos de splits encadenados
  * legs hijos ocultos de escenarios split-cancel / unsplit / restore

  Además, `updatedAt` se actualiza cuando cambia la visibilidad del viaje, por lo que el sondeo por `updatedSince` o `updatedAtRange` puede capturar estos eventos de forma confiable.

  ### Qué significa `isDeleted`

  Cuando `includeDeleted=true`:

  * `isDeleted=true` significa que el viaje está eliminado o ya no es visible y debe considerarse inactivo para la sincronización
  * `isDeleted=false` significa que el viaje es un leg visible actual

  ### Escenarios comunes

  | Escenario                                             | Antes                                                  | Después (con `includeDeleted: true`)                                                                                  |
  | ----------------------------------------------------- | ------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------- |
  | Viaje `555` dividido en `555-1`, `555-2`              | `555` desaparecía silenciosamente                      | `555` se devuelve con `isDeleted: true`                                                                               |
  | Viaje `555-2` dividido nuevamente en `555-3`, `555-4` | `555-2` desaparecía silenciosamente                    | `555-2` se devuelve con `isDeleted: true`                                                                             |
  | Split cancelado / unsplit / restaurado                | los legs de split ocultos desaparecían silenciosamente | los legs de split ocultos se devuelven con `isDeleted: true`, el viaje activo restaurado permanece `isDeleted: false` |

  ### Ejemplo

  Para una carga con comportamiento de split encadenado como `1110758`:

  | Viaje       | isDeleted | Significado                                 |
  | ----------- | --------: | ------------------------------------------- |
  | `1110758`   |    `true` | Viaje base reemplazado                      |
  | `1110758-1` |   `false` | Leg activo                                  |
  | `1110758-2` |    `true` | Leg hijo reemplazado por un split posterior |
  | `1110758-3` |   `false` | Leg activo                                  |
  | `1110758-4` |   `false` | Leg activo                                  |

  ### Endpoint afectado

  ```http theme={null}
  POST /p/v1.0/trips/search
  ```

  ### ¿Por qué?

  Esta mejora proporciona:

  * detección confiable de tombstones para viajes invisibles y reemplazados
  * mejor soporte para el sondeo con `updatedSince` y `updatedAtRange`
  * sincronización más consistente para escenarios de split, re-split, cancel-split y restore

  <br />
</Update>

<Update label="April 15, 2026" description="Mejoras de webhooks en la API pública: intentos de entrega, razón de estado y exportación de logs de entrega" tags={["Added", "Webhooks"]}>
  ### ¿Qué hay de nuevo?

  Hemos ampliado las capacidades de webhooks de la API pública con nuevos metadatos de entrega, payloads de eventos más ricos y soporte de exportación para los logs de entrega de webhooks. Estas actualizaciones facilitan la monitorización, depuración y procesamiento seguro de las integraciones de webhooks.

  ### ¿Qué cambió?

  Anteriormente, los consumidores de webhooks no recibían un encabezado de intento de entrega, los payloads de webhooks de visibilidad/estado no incluían una razón de estado legible por humanos, y no había un endpoint dedicado de exportación de logs de entrega en el esquema publicado. Además, los filtros de logs de entrega aceptaban previamente valores de cadena únicos.

  Ahora, la API pública incluye los siguientes cambios de webhooks:

  ```http theme={null}
  GET /p/v{version}/webhooks/{webhookId}/delivery-logs/export
  ```

  ### Encabezado de intento de entrega

  Alvys ahora incluye un encabezado `X-Alvys-Attempt` en cada solicitud de entrega de webhook saliente. El valor representa el número de intento de entrega como una cadena entera.

  | Encabezado        | Tipo          | Descripción                                                         |
  | ----------------- | ------------- | ------------------------------------------------------------------- |
  | `X-Alvys-Attempt` | cadena entera | Número de intento de entrega para la solicitud de webhook saliente. |

  | Valor | Significado                                             |
  | ----- | ------------------------------------------------------- |
  | `1`   | Primer intento de entrega                               |
  | `2`   | Primer reintento tras retroceso de 10 segundos          |
  | `3`   | Segundo reintento tras retroceso de 30 segundos         |
  | `4`   | Tercer y último reintento tras retroceso de 60 segundos |

  Esto puede utilizarse para soportar procesamiento idempotente, suprimir advertencias de duplicados y rastrear el comportamiento de reintentos.

  ### `statusReason` añadido a los payloads de webhook

  Los payloads de webhooks salientes para eventos de visibilidad y estado ahora incluyen un campo `statusReason`. Este campo proporciona la descripción legible de la razón, distinta del código de razón.

  Ejemplo:

  ```json theme={null}
  {
    "statusReason": "Normal Status"
  }
  ```

  ### Exportación de logs de entrega

  Un nuevo endpoint de exportación de logs de entrega de webhooks ya está disponible en el nuevo esquema: `GET /p/v{version}/webhooks/{webhookId}/delivery-logs/export`. Soporta exportación en CSV y JSON y utiliza los mismos filtros que el endpoint de listado de logs de entrega. La descripción del esquema también confirma que la exportación admite hasta 25.000 filas en total.

  #### Parámetros de consulta

  | Parámetro   | Tipo               | Descripción                                                            |
  | ----------- | ------------------ | ---------------------------------------------------------------------- |
  | `webhookId` | string             | Identificador del webhook cuyos logs se exportarán.                    |
  | `Format`    | string             | Formato de exportación. Los valores admitidos incluyen `csv` y `json`. |
  | `Page`      | integer            | Índice de última página (base 0) a incluir en la exportación.          |
  | `PageSize`  | integer            | Número de filas por página. Máximo 100, predeterminado 50.             |
  | `Status`    | array of strings   | Filtrar por uno o más estados de entrega.                              |
  | `EventType` | array of strings   | Filtrar por uno o más tipos de eventos de webhook.                     |
  | `StartDate` | string (date-time) | Inicio del rango de fechas.                                            |
  | `EndDate`   | string (date-time) | Fin del rango de fechas.                                               |

  #### Comportamiento de exportación

  El nuevo esquema documenta el siguiente comportamiento de resolución de formato para el endpoint de exportación:

  1. `Format=csv` o `Format=json` en la cadena de consulta tiene precedencia cuando se proporciona.
  2. De lo contrario, se utiliza el encabezado `Accept`.
  3. De lo contrario, la respuesta usa JSON por defecto.

  ### Cambio incompatible: los filtros de logs de entrega ahora aceptan arreglos

  El endpoint de listado de logs de entrega cambió la forma de sus filtros entre el esquema antiguo y el nuevo. Anteriormente, tanto `Status` como `EventType` eran cadenas únicas. En el nuevo esquema, ambos son arreglos de cadenas.

  #### Antes

  ```json theme={null}
  {
    "status": "failed",
    "eventType": "load.updated"
  }
  ```

  #### Después

  ```json theme={null}
  {
    "status": ["failed"],
    "eventType": ["load.updated"]
  }
  ```

  Este cambio también aplica al endpoint de exportación, donde `Status` y `EventType` están definidos como arreglos.

  ### Endpoints afectados

  * `GET /p/v{version}/webhooks/{webhookId}/delivery-logs`
  * `GET /p/v{version}/webhooks/{webhookId}/delivery-logs/export`

  ### ¿Por qué?

  Estas mejoras proporcionan:

  * mejor visibilidad de reintentos para los consumidores de webhooks
  * contexto de estado más claro en los payloads salientes
  * exportación y auditoría más sencillas del historial de entregas de webhooks
  * filtrado más flexible para consultas y exportaciones de logs de entrega

  <br />
</Update>

<Update label="April 13, 2026" description="Mejoras en la API pública para cargas, viajes, transportistas, tenders y esquemas de respuesta principales" tags={["Improved", "Tenders", "Carriers"]}>
  ### ¿Qué hay de nuevo?

  Hemos entregado mejoras adicionales en la API pública en **cargas**, **viajes**, **transportistas**, **tenders** y varios esquemas de respuesta existentes. Estos cambios mejoran la fiabilidad de la sincronización, exponen más datos operativos y hacen que los endpoints relacionados sean más consistentes.

  ### ¿Qué cambió?

  Anteriormente, varios campos y comportamientos importantes estaban ausentes del esquema publicado, eran inconsistentes entre endpoints relacionados o no estaban totalmente expuestos a las integraciones.

  Ahora, la API pública incluye los siguientes cambios confirmados:

  #### Cargas

  Las respuestas de cargas ahora incluyen:

  ```json theme={null}
  {
    "tenderId": "string | null",
    "requiredEquipment": [
      "Reefer"
    ]
  }
  ```

  Además:

  * las cargas huérfanas ahora se tratan como inexistentes
  * los totales de búsqueda de cargas excluyen las cargas abandonadas sin viajes
  * las operaciones de documentos y notas de carga ahora devuelven `404` para cargas huérfanas

  #### Viajes

  Las respuestas de viajes ahora incluyen:

  ```json theme={null}
  {
    "orderNumber": "string | null"
  }
  ```

  El comportamiento de sincronización de viajes también fue mejorado:

  * los viajes divididos o invisibles ahora pueden devolverse como `isDeleted: true` cuando `includeDeleted=true`
  * `GET /p/v{version}/trips` ahora soporta `includeDeleted`
  * `POST /p/v{version}/trips/search` ahora permite `updatedAtRange` como único filtro
  * las referencias de carga de tipo `service_exception` ahora están expuestas
  * los payloads de transportista están alineados entre la obtención de un solo viaje y la búsqueda de viajes

  #### Transportistas

  Los resultados de búsqueda de transportistas ahora incluyen transportistas en estado `DoNotLoad`, que antes se omitían incluso cuando eran referenciados por viajes.

  #### Tenders

  Los objetos `references[]` de la solicitud de tender ahora soportan un campo `type`, habilitando el enrutamiento de referencias tipadas.

  #### Actualizaciones adicionales del esquema de respuesta

  El nuevo esquema también confirma cambios adicionales en el modelo de respuesta fuera de los flujos de registro de pagos:

  * `CarrierResponse` ahora incluye:

    * `PaymentMethod`
    * `ExternalIds`
    * `FactoringCompany`
  * `DriverResponse`, `TruckResponse` y `TrailerResponse` ahora incluyen:

    * `LicenseCountry`
  * `FuelResponse` ahora incluye:

    * `Description`
  * `FuelResponsePumpLocation` ahora incluye:

    * `State`

  #### Actualizaciones del esquema de tarifas de viaje

  Los esquemas relacionados con las tarifas de viajes se ampliaron con estructuras y campos adicionales:

  * `DriverRatePolicyResponse` ahora incluye:

    * `CustomerLineHaulDeductionRate`
    * `PerMileRate`
    * `PerMileDeductionRate`
  * `PerLoadRate` ahora utiliza un `PerLoadRateDto` dedicado
  * `MileageRateDto` ahora incluye:

    * `UseHighestTier`
  * `PerTripRateDto` ahora incluye:

    * `Tiers`
    * `MileageType`
  * `PerTripRateDto.Rate` ahora está marcado como obsoleto en el esquema

  #### Actualizaciones de documentación de respuestas de error

  El nuevo esquema también añade documentación más amplia de respuestas de error en muchos endpoints existentes que no son de webhook:

  * `401 Unauthorized`
  * `403 Forbidden`
  * `429 Too Many Requests`

  ### ¿Por qué?

  Estas mejoras proporcionan:

  * mejor fiabilidad de sincronización de cargas y viajes para integraciones de sondeo
  * identificación más clara de las cargas originadas por tender
  * mejor visibilidad del vínculo con la orden a nivel de viaje
  * resultados de búsqueda de transportistas más completos
  * mayor consistencia entre endpoints de viaje relacionados
  * payloads de datos maestros más ricos para transportistas, conductores, camiones, remolques y registros de combustible
  * esquemas de tarifas de viaje más expresivos

  <br />

  <br />
</Update>

<Update label="March 13, 2026" description="Gestiona llegadas, salidas y citas de paradas mediante la Public API" tags={["Added", "Trips"]}>
  ### ¿Qué hay de nuevo?

  La Public API ahora admite la ejecución completa de viajes a nivel de parada: leer las paradas de un viaje, registrar (o borrar) llegadas, registrar salidas y gestionar citas de parada — para que los eventos de despacho puedan fluir a Alvys desde tus propios sistemas en tiempo real.

  ### ¿Qué cambió?

  Anteriormente, las llegadas, salidas y cambios de cita de paradas solo podían registrarse dentro de la plataforma Alvys.

  Ahora, la Public API incluye los siguientes endpoints:

  ```http theme={null}
  GET    /api/p/v{version}/trips/{tripId}/stops
  GET    /api/p/v{version}/trips/{tripId}/stops/{stopId}
  PUT    /api/p/v{version}/trips/{tripId}/stops/{stopId}/arrival
  DELETE /api/p/v{version}/trips/{tripId}/stops/{stopId}/arrival
  PUT    /api/p/v{version}/trips/{tripId}/stops/{stopId}/departure
  PUT    /api/p/v{version}/trips/{tripId}/stops/{stopId}/appointment
  ```

  * [**Record stop arrival**](/en/api/reference/trips/record-stop-arrival) — el cuerpo toma una marca de tiempo `arrivedAt` obligatoria; devuelve la parada actualizada.
  * [**Clear stop arrival**](/en/api/reference/trips/clear-stop-arrival) — elimina una llegada registrada previamente.
  * [**Record stop departure**](/en/api/reference/trips/record-stop-departure) — el cuerpo toma una marca de tiempo `departedAt` obligatoria; devuelve `422` si la parada no está en un estado que permita salida.
  * [**Set stop appointment**](/en/api/reference/trips/set-stop-appointment) — actualiza `scheduleType`, `loadingType` y la ventana de cita de la parada.

  Todos los endpoints de mutación devuelven el `StopResponse` actualizado, de modo que los llamadores obtienen el estado fresco sin una lectura posterior.

  ### ¿Por qué?

  Los proveedores EDI, las apps de conductor y los sistemas de despacho generan eventos de llegada/salida fuera de Alvys. Estos endpoints permiten que esos eventos aterricen directamente en las paradas del viaje, manteniendo precisos los estados, las marcas de tiempo y la facturación posterior (p. ej. detención).

  <br />
</Update>

<Update label="March 2, 2026" description="Endpoints de notas de carga añadidos a la Public API" tags={["Added", "Loads"]}>
  **Release Date:** March 2, 2026 (endpoints), April 30, 2026 (`CreatedById`)

  ### ¿Qué hay de nuevo?

  Ahora puedes listar, crear y eliminar notas de carga a través de la Public API — manteniendo el comentario operativo sincronizado entre Alvys y tus sistemas externos.

  ### ¿Qué cambió?

  Anteriormente, las notas de carga solo eran accesibles dentro de la plataforma Alvys.

  Ahora, la Public API incluye:

  ```http theme={null}
  GET    /api/p/v1/loads/{loadNumber}/notes
  POST   /api/p/v1/loads/{loadNumber}/notes
  DELETE /api/p/v1/loads/{loadNumber}/notes/{noteId}
  ```

  * **List load notes** — devuelve todas las notas de la carga.
  * **Create load note** — el cuerpo toma `description`, `noteType` y un `id` opcional proporcionado por el cliente; devuelve `201` con la nota creada.
  * **Delete load note** — devuelve `204` en caso de éxito.

  ### El cuerpo de respuesta incluye

  * `Id`, `Description`, `NoteType`
  * `CreatedAt`, `CreatedBy`
  * `CreatedById` — el identificador único del usuario que creó la nota *(añadido en abril de 2026)*, de modo que las integraciones pueden atribuir notas a un usuario por id en lugar de analizar nombres para mostrar.

  Las notas en cargas huérfanas o inaccesibles devuelven `404`.

  ### ¿Por qué?

  Las notas llevan contexto de despacho — instrucciones especiales, historial de excepciones, compromisos con clientes. Exponerlas mediante la API permite que las integraciones lean ese contexto y escriban el suyo propio, sin doble entrada en dos sistemas.
</Update>

<Update label="February 23, 2026" description="Los webhooks de Alvys ahora disponibles para eventos del ciclo de vida de tenders" tags={["Webhooks", "Tenders"]}>
  ## ¿Qué hay de nuevo?

  Alvys ahora admite **Webhooks** — una forma segura de recibir notificaciones de eventos en tiempo real directamente desde Alvys a tu sistema.

  En lugar de consultar la API periódicamente para obtener actualizaciones, tu sistema ahora puede suscribirse a eventos y recibirlos automáticamente a través de llamadas HTTPS seguras.

  **En esta versión inicial, los Webhooks admiten únicamente eventos relacionados con tenders.**
  Se introducirán dominios de eventos adicionales (como cargas o viajes) en futuras versiones.

  Esta versión establece la capa de base para la distribución de eventos en tiempo real en Alvys.

  ## Qué puedes hacer

  Con los Webhooks, puedes:

  * Recibir **eventos del ciclo de vida de tenders** en tiempo real
  * Activar automáticamente flujos de trabajo en tu sistema
  * Mejorar la velocidad y capacidad de respuesta de la integración

  ## Incluido en esta versión

  ### Entrega de eventos

  Alvys envía solicitudes HTTPS `POST` al endpoint que configuraste cada vez que ocurre un **evento de tender** suscrito.

  Cada entrega incluye:

  * Tipo de evento
  * ID único del evento
  * Marca de tiempo
  * Firma HMAC segura

  Los Webhooks utilizan un **modelo de entrega al menos una vez** con reintentos automáticos para garantizar la confiabilidad.

  ### Reintentos automáticos

  Si tu endpoint no está disponible temporalmente, Alvys reintentará la entrega automáticamente.

  Cada evento puede intentarse hasta cuatro veces.

  Los reintentos ocurren cuando:

  * Tu endpoint devuelve un error del servidor (5xx)
  * Ocurre un timeout
  * Ocurre una falla temporal de red

  Los reintentos no ocurren para errores permanentes del cliente (la mayoría de las respuestas 4xx).

  ### Seguridad y verificación

  Los Webhooks incluyen:

  * Verificación de firma HMAC-SHA256
  * Protección contra reenvíos mediante marcas de tiempo
  * Entrega exclusivamente por HTTPS
  * Verificación de propiedad del endpoint durante la configuración

  Esto garantiza que los eventos sean auténticos y se transmitan de forma segura.

  ## Por qué esto es importante

  Los Webhooks permiten integraciones en tiempo real y orientadas a eventos entre Alvys y tus sistemas.

  Esta versión sienta las bases para:

  * Integraciones EDI sobre API
  * Flujos de trabajo automatizados de tenders
  * Respuesta operativa más rápida
  * Integraciones seguras con terceros

  Futuras versiones ampliarán el soporte de webhooks a dominios de negocio adicionales.

  ## Documentación

  Para obtener detalles completos de implementación, consulta:

  * **[Ciclo de vida y configuración de Webhooks](/en/api/reference/webhooks/webhook-lifecycle-configuration)**
  * **[Entrega y confiabilidad de eventos](/en/api/reference/webhooks/event-delivery-reliability)**
  * **[Seguridad y verificación de firmas](/en/api/reference/webhooks/security-signature-verification)**

  Estas guías cubren la configuración de suscripciones, el comportamiento de reintentos, las reglas de desactivación automática, la validación de firmas y las mejores prácticas para construir integraciones robustas.

  <br />

  <Warning>
    **Aviso de disponibilidad de Webhooks**

    Actualmente los Webhooks están disponibles bajo solicitud.
    Para habilitar esta funcionalidad en tu cuenta, comunícate con tu Customer Success Manager o Implementation Manager.
  </Warning>
</Update>

<Update label="February 13, 2026" description="Campos de temperatura del viaje y equipo requerido agregados al cuerpo de respuesta del viaje" tags={["Added", "Trips"]}>
  ### ¿Qué hay de nuevo?

  Hemos añadido dos nuevos campos a los endpoints **Trips** en la API Pública: **Temperature** y **RequiredEquipment**. Estos campos proporcionan visibilidad sobre los requisitos de temperatura y las especificaciones de equipo para cada viaje.

  ### ¿Qué cambió?

  Anteriormente, los requisitos de temperatura y los requisitos de equipo normalizados no se exponían en la API Pública.

  Ahora, la respuesta incluye las siguientes nuevas propiedades:

  ```json theme={null}
  "Temperature": {
    "SetpointTemperature": 70.0,
    "SetpointTemperatureMax": 75.0,
    "ControlMode": "Start/Stop"
  },

  "RequiredEquipment": [
    "Reefer"
  ]
  ```

  #### Temperature

  El objeto `Temperature` representa los ajustes de temperatura requeridos para viajes con control de temperatura.

  * **SetpointTemperature** – La temperatura objetivo requerida.
  * **SetpointTemperatureMax** – Temperatura máxima opcional cuando se define un rango.
  * **ControlMode** – Modo operativo esperado (`Continuous` o `Start/Stop`).

  Si no existe un requisito de temperatura para el viaje, este campo devolverá `null`.

  #### RequiredEquipment

  El campo `RequiredEquipment` ahora se devuelve como un arreglo de tipos de equipo requeridos para el viaje.

  Ejemplos:

  ```json theme={null}
  "RequiredEquipment": ["Reefer", "Van"]
  "RequiredEquipment": ["Van"]
  "RequiredEquipment": ["Flatbed", "StepDeck"]
  ```

  Si no hay un requisito de equipo definido, este campo devolverá `null`.

  ### Endpoints afectados:

  * `POST /api/p/{version}/trips/search`
  * `GET /api/p/{version}/trips/{id}`

  ### ¿Por qué?

  Estas adiciones proporcionan:

  * Mejor visibilidad de los requisitos de viajes con control de temperatura
  * Datos de equipo estructurados para una validación e integración más sencillas
  * Mejor soporte para flujos de trabajo de cumplimiento y aplicaciones de seguimiento personalizadas

  Esta actualización mejora la claridad y las capacidades de integración manteniendo la compatibilidad hacia atrás.
</Update>

<Update label="January 26, 2026" description="Referencias personalizadas para viajes, conductores, camiones y remolques" tags={["Added", "Trips", "Drivers", "Trucks", "Trailers"]}>
  ### ¿Qué hay de nuevo?

  Las referencias personalizadas — identificadores clave/valor definidos por el tenant configurados en el perfil de tu empresa Alvys — ahora se exponen en la Public API en **viajes**, **conductores**, **camiones** y **remolques**.

  ### ¿Qué cambió?

  Anteriormente, las referencias personalizadas solo eran visibles dentro de la plataforma Alvys.

  Ahora, las respuestas correspondientes de get-by-id y búsqueda incluyen una colección `references`:

  ```json theme={null}
  "references": [
    {
      "id": "string",
      "referenceId": "string",
      "name": "string",
      "value": "string",
      "type": "Text",
      "access": "Public",
      "origin": "string"
    }
  ]
  ```

  ### Endpoints afectados

  * `GET /api/p/v{version}/trips/{id}` y `POST /api/p/v{version}/trips/search`
  * `GET /api/p/v{version}/drivers/{id}` y `POST /api/p/v{version}/drivers/search`
  * `GET /api/p/v{version}/trucks/{id}` y `POST /api/p/v{version}/trucks/search`
  * `GET /api/p/v{version}/trailers/{id}` y `POST /api/p/v{version}/trailers/search`

  Solo se devuelven las referencias configuradas como visibles para la Public API — la visibilidad de referencias se controla por tipo de referencia en el perfil de tu empresa.

  ### ¿Por qué?

  La mayoría de las flotas rastrean identificadores externos que no encajan en campos estándar — ids de nómina, ids de ELD, números de póliza de seguro, claves de sistemas heredados. Las referencias personalizadas te permiten modelarlos en Alvys, y este cambio las hace disponibles para cada integración que necesite unir registros de Alvys con sistemas externos.
</Update>

<Update label="October 24, 2025" description="Visibilidad mejorada de tarifas del conductor en el endpoint de viajes" tags={["Added", "Visibility", "Drivers"]}>
  ### ¿Qué hay de nuevo?

  Hemos introducido la nueva estructura **RatesV2** para conductores y owner-operators en la API Pública de Trips.
  Esta estructura proporciona un desglose detallado de cómo se calculó el pago de cada conductor con base en las reglas y políticas de tarifa aplicadas.

  ### ¿Qué cambió?

  Anteriormente, los datos de pago del conductor bajo `Driver1`, `Driver2` y `OwnerOperator` incluían únicamente arreglos `Rates[]` simples con campos limitados (por ejemplo, `rate`, `rateType`, `source`).

  Ahora, la respuesta incluye un arreglo **`RatesV2`**, que contiene todas las reglas aplicadas, sus tipos, montos y partidas de línea calculadas.

  Cada entrada de `RatesV2[]` contiene un `PolicyId`, `PolicyName` únicos, y uno o más componentes de tarifa detallados, tales como:

  ```json theme={null}
   "RatesV2": [
                      {
                          "PolicyId": "c00fda1001ec4a11100affdb0234de00",
                          "PolicyName": "Custom Rate",
                          "PerTripRate": {
                              "Rate": 250.0,
                              "RateId": "1",
                              "RateName": "Per Trip",
                              "LineItems": [
                                  {
                                      "Description": "1 trip @ $250",
                                      "Amount": {
                                          "Amount": 250.0,
                                          "Currency": 840
                                      }
                                  }
                              ]
                          }
                      },
                      {
                          "PolicyId": "a00fba1001ec4a11100aaddff0234de00",
                          "PolicyName": "Public API",
                          "TripValuePercentageRate": {
                              "Percentage": 25.0,
                              "RateId": "2",
                              "RateName": "% of Trip Value",
                              "LineItems": [
                                  {
                                      "Description": "25% of $3,800",
                                      "Amount": {
                                          "Amount": 950.0,
                                          "Currency": 840
                                      }
                                  }
                              ]
                          }
                      }
                  ]
  ```

  ### Endpoints afectados

  * `GET /api/p/{version}/trips`
  * `POST /api/p/{version}/trips/search`

  ### ¿Por qué?

  Este cambio expone la **lógica de cálculo de tarifas del conductor** utilizada en la UI de Alvys, permitiendo a los integradores:

  * Comprender qué reglas y políticas se aplicaron para determinar cada pago.
  * Alinear las integraciones de backend con el nuevo motor interno de políticas de pago para obtener reportes y conciliaciones consistentes.

  <br />

  <Warning>
    Nota importante

    Esta actualización es **parcialmente compatible hacia atrás**:

    * El campo heredado `Rates[]` sigue existiendo y se devuelve en las respuestas de la API.
    * Para **nuevos viajes creados después de la migración** a Driver Settlement (DS), el arreglo `Rates[]` **siempre estará vacío**.
    * Para **viajes creados antes de la migración**, `Rates[]` aún puede contener datos históricos, pero puede estar **desincronizado** con `RatesV2[]` si se agregaron nuevas tarifas después de la migración.
    * Todos los datos de tarifas actuales y futuros ahora se proporcionan exclusivamente en el arreglo **`RatesV2[]`**.
    * Las integraciones deben **actualizar su lógica** para usar `RatesV2[]` como fuente de verdad para los detalles de pago del conductor y owner-operator.
    * El campo heredado `Rates[]` permanecerá disponible temporalmente para compatibilidad hacia atrás, pero será **totalmente descontinuado más adelante**.

    Cada tipo de tarifa (por ejemplo, `TripValuePercentageRate`, `PerTripRate`, `MinimumPayRate`, etc.) ahora se proporciona como un objeto estructurado con `LineItems[]` adicionales para desgloses detallados.
  </Warning>

  <br />
</Update>

<Update label="October 9, 2025" description="Nuevos endpoints para gestionar deducciones" tags={["Added", "Deductions"]}>
  ### ¿Qué hay de nuevo?

  Se ha añadido un nuevo módulo de **Deductions** a la API Pública de Alvys.
  Estos endpoints permiten a las integraciones crear, buscar, recuperar y eliminar registros de deducciones asociados a conductores o camiones.
  Una deducción representa un **ajuste financiero específico del activo** (por ejemplo, honorarios de pruebas de drogas, adelantos de combustible o reembolsos) y siempre está vinculada a un **DriverId** o **TruckId** específico, pero nunca a ambos.

  En esta etapa, solo se admiten deducciones **únicas (Once)**.

  ***

  ### ¿Qué cambió?

  **Nuevos endpoints:**

  | Método   | Endpoint                              | Descripción                                                      |
  | -------- | ------------------------------------- | ---------------------------------------------------------------- |
  | `GET`    | `/api/p/v{version}/deductions/{id}`   | Recupera una deducción por su ID único.                          |
  | `POST`   | `/api/p/v{version}/deductions/search` | Busca deducciones por fecha, conductor, camión u owner operator. |
  | `POST`   | `/api/p/v{version}/deductions/once`   | Crea una deducción única para un conductor o un camión.          |
  | `DELETE` | `/api/p/v{version}/deductions/{id}`   | Elimina una deducción específica por su ID único.                |

  **Reglas de validación:**

  * Una deducción debe incluir **`DriverId` o `TruckId`** — uno de ellos es obligatorio.
  * **`OwnerOperatorId`** es opcional y puede utilizarse únicamente para sobrescribir el propietario actual del activo. Nunca es el sujeto principal de la deducción.
  * Si se proporciona `DriverId` → la deducción aparece en la lista de deducciones de ese conductor.
  * Si se proporciona `TruckId` → la deducción aparece en la lista de deducciones de ese camión.
  * Para crear una deducción, el monto debe ser **negativo** y menor que **- 1.00**.
  * Solo se admite la frecuencia `"Once"`.
  * Requiere un token Bearer válido con el scope apropiado (`deduction:read`, `deduction:create` o `deduction:delete`).

  ***

  ### ¿Por qué?

  Esta versión introduce una forma consistente y segura de gestionar **deducciones únicas** a través de la API Pública.
  Permite la sincronización automatizada de datos de deducciones entre sistemas financieros y de nómina, manteniendo la plena propiedad y el contexto del activo dentro de Alvys.
</Update>

<Update label="September 30, 2025" description="La API Pública ahora admite la obtención de documentos en las entidades principales" tags={["Added"]}>
  Hemos añadido nuevos **endpoints de obtención de documentos** a la API Pública. Estos endpoints permiten recuperar los documentos subidos para carriers, drivers, loads, trips, trucks y trailers.

  ***

  ### ¿Qué cambió?

  Anteriormente, los documentos solo estaban disponibles a través de la UI interna y no se exponían en la API Pública.

  Ahora, los siguientes nuevos endpoints están disponibles para recuperar los documentos asociados con cada tipo de entidad:

  **Endpoints añadidos:**

  `GET /api/p/{version}/carriers/{carrierId}/documents`

  `GET /api/p/{version}/drivers/{driverId}/documents`

  `GET /api/p/{version}/loads/{loadNumber}/documents`

  `GET /api/p/{version}/trips/{tripId}/documents`

  `GET /api/p/{version}/trucks/{truckId}/documents`

  `GET /api/p/{version}/trailers/{trailerId}/documents`

  ***

  ### Ejemplo de respuesta

  Cada endpoint devuelve un arreglo de objetos de documento, proporcionando todos los documentos vinculados a la entidad especificada. Cada documento incluye detalles como tipo, tamaño, quien lo subió y hora de carga, junto con un enlace de descarga seguro. El `DownloadUrl` es válido por 10 minutos e incluye una marca de tiempo `ExpiresAt`.

  ```json theme={null}
  [
    {
      "id": "a314c7cd-783a-4807-8771-06406a9e490a",
      "AttachmentPath": "Loads-1759237626.pdf",
      "AttachmentType": "Customer Rate Confirmation",
      "AttachmentSize": 170225,
      "UploadedAt": "2025-09-30T13:07:07+00:00",
      "ParentId": "3022259",
      "ParentType": "Load",
      "UploadedBy": "7190175eecc3408e90d7173f4ece0e59",
      "DownloadUrl": "https://alvysqastorage.blob.core.windows.net/tl743/Loads-1759237626.pdf?...",
      "ExpiresAt": "2025-09-30T15:12:15.9506343+00:00"
    }
  ]
  ```

  ***

  ### ¿Por qué?

  Esta mejora mejora la transparencia y flexibilidad al hacer los documentos accesibles a través de la API Pública. Admite casos de uso más amplios, permitiendo a los sistemas externos integrarse sin problemas con los datos y flujos de trabajo de Alvys.

  <br />
</Update>

<Update label="September 24, 2025" description="Se introdujo la oficina de la carga en la API Pública" tags={["Added", "Loads"]}>
  ### ¿Qué hay de nuevo?

  Hemos añadido el campo **Load Office** a la API Pública. Este campo ahora se devuelve en el endpoint de **Loads**, proporcionando visibilidad sobre a qué oficina pertenece una carga.

  ### ¿Qué cambió?

  Anteriormente, la información de oficina de la carga no se exponía en la API Pública.

  Ahora, la respuesta incluye la siguiente nueva propiedad:

  ```json theme={null}
  "OfficeId": "string",
  ```

  Este valor corresponde al ID interno de la oficina asociada con la carga.

  ### Endpoints afectados:

  * `POST /api/p/{version}/loads/search`
  * `GET /api/p/{version}/loads/{id}`

  ### ¿Por qué?

  Este cambio proporciona transparencia sobre la propiedad de las cargas por oficina, respaldando reportes a nivel de oficina e integraciones que requieren filtrar o agrupar cargas por su oficina asignada.

  <br />

  <br />
</Update>

<Update label="September 8, 2025 · 4:28 PM" description="Endpoints de carga de documentos ahora disponibles en la API Pública" tags={["Added"]}>
  ### ¿Qué hay de nuevo?

  Añadimos un nuevo conjunto de endpoints de carga de documentos que permiten adjuntar archivos directamente a Carriers, Drivers, Loads, Trailers, Trips y Trucks. Cada endpoint admite subidas de `multipart/form-data` con validación en el tamaño del archivo y el tipo de documento.

  📂**Subidas de archivos hasta 25 MB** (PDF, JPEG, PNG)

  🧾 **Validación específica por entidad** → Cada entidad admite únicamente su propia lista de `DocumentType` (por ejemplo, `Carrier Agreement`, `Driver License`, `Proof of Deliver`)

  🗂️ **Metadatos estandarizados** → Cada subida devuelve `AttachmentPath`, `AttachmentType`, `AttachmentSize`, `UploadedAt` y la referencia a la entidad padre

  🔑 **Autenticación y scopes** → Requiere un token Bearer válido con scope de lectura/actualización para la entidad objetivo

  ***

  ### ¿Qué cambió?

  * **Nuevos endpoints**:

    * `POST /api/p/v{version}/carriers/{carrierId}/document`
    * `POST /api/p/v{version}/drivers/{driverId}/document`
    * `POST /api/p/v{version}/loads/{loadNumber}/document`
    * `POST /api/p/v{version}/trailers/{trailerId}/document`
    * `POST /api/p/v{version}/trips/{tripId}/document`
    * `POST /api/p/v{version}/trucks/{truckId}/document`

  * **Validación por entidad**:

    * **Carrier**→ Carrier Agreement, Carrier Application, Carrier Authority, Carrier Onboarding, Other Documents
    * **Driver**→ License, Drug Test, Medical (renombrado sugerido: Medical Card), W9 Form, Operating Authority, Other Documents
    * **Truck/Trailer** → Motor Vehicle Record, Vehicle Image, Inspection Certificate, Certificate of Insurance (COI), Insurance Certificate, Other Documents
    * **Loads**→ Customer Rate and Load Confirmation, Customer Load Confirmation, Customer Rate Confirmation, Signed Customer Rate Confirmation, Proof of Delivery, Proof of Pickup, Bill of Lading, Shipping Labels
    * **Trips** → Proof of Delivery (POD), Bill of Lading (BOL), Carrier Rate Confirmation, Load Manifest, Trip Report, Temperature Log, Proof of Pickup, Scale Ticket, Notice of Assignment (NOA), Shipping Labels

  * **Manejo de errores estandarizado**:

    `400` `DocumentType` inválido o archivo demasiado grande

    `401` token inválido/expirado

    `403` scopes faltantes

    `404` entidad padre no encontrada/eliminada

    `415` tipo de contenido no soportado

    `429` límite de tasa excedido

  ***

  ### Ejemplo — Subir documento a Load

  ```bash theme={null}
  curl -X POST "{{host}}/api/p/v1/loads/1006321/document" \
    -H "Authorization: Bearer $TOKEN" \
    -H "Content-Type: multipart/form-data" \
    -F "File=@Test_File.pdf" \
    -F "DocumentType=Bill of Lading"
  ```

  **Respuesta:**

  ```json theme={null}
  {
    "id": "4b5c38bd-005e-4903-a4ee-45ca5e86411a",
    "AttachmentPath": "DOC-1757343192.jpeg",
    "AttachmentType": "Bill of Lading",
    "AttachmentSize": 5245329,
    "UploadedAt": "2025-09-08T14:53:12Z",
    "ParentId": "1006321",
    "ParentType": "Load"
  }
  ```

  ***

  ### ¿Por qué?

  Esta mejora proporciona una **forma estandarizada y segura** de subir y gestionar documentos en todas las entidades principales. Al aplicar validación de tamaño y tipo de archivo, además de reglas de `DocumentType` específicas por entidad, mejoramos el **cumplimiento y la integridad de los datos**. Estos endpoints también habilitan casos de uso de automatización, como adjuntar automáticamente Proof of Delivery, Insurance Certificates o Rate Confirmations durante los flujos de trabajo operativos.

  <br />
</Update>

<Update label="September 8, 2025 · 4:18 PM" description="Nuevos endpoints para detalles de ubicación de empresa" tags={["Added"]}>
  ### ¿Qué hay de nuevo?

  Añadimos un nuevo **Locations Controller** a la API Pública. Esto te permite obtener y buscar detalles de ubicaciones de empresas (por ejemplo, Terminals, Shippers/Consignees, Cold Warehouses, Dry Warehouses).

  * **Búsqueda por ID o Company Number**: Recupera una sola ubicación por `id` único o `companyNumber`.
  * **Búsqueda flexible**: Filtra por `Statuses`, `LocationIds` o `CreatedDateRange`.
  * **Detalles más ricos**: Obtén el nombre de la empresa, tipo, dirección, contactos y notas directamente en la respuesta.

  ***

  ### &#x20;¿Qué cambió?

  * **Nuevos endpoints**:

    * `GET /api/p/v{version}/locations` → Búsqueda de una sola ubicación por `id` o `companyNumber`.
    * `POST /api/p/v{version}/locations/search` → Buscar y paginar resultados.

  * **El cuerpo de la respuesta incluye**:

    * Principal: `Id`, `Name`, `CompanyNumber`, `Type`, `Status`
    * Dirección: `PhysicalAddress { Street, City, State, ZipCode }`
    * Contactos: `Email[]`, `Phone[]`, `Fax`
    * Metadatos: `DateCreated`, `ExternalId`
    * Notas: `[ { Id, Description, NoteType, Time, User } ]`

  * **Compatibilidad hacia atrás**: Sin cambios en los payloads existentes de load/trip stop. Las paradas continúan exponiendo `companyId`, pero ahora los clientes pueden resolver esos IDs a través del Locations Controller para obtener más contexto.

  ***

  ### Nuevos endpoints

  * `GET /api/p/v{version}/locations`
  * `POST /api/p/v{version}/locations/search`

  ***

  ### ¿Por qué?

  Anteriormente, las paradas en cargas y viajes solo incluían un **companyId**, lo que dificultaba identificar la empresa detrás de cada parada. Con esta versión, los clientes pueden resolver esos IDs en **nombres, direcciones y detalles completos**. Esto mejora la precisión de los reportes, la visibilidad operativa y la usabilidad general, sin romper las integraciones existentes.

  <br />
</Update>

<Update label="September 4, 2025" description="Endpoints de combustible mejorados con detalles de fecha de transacción y cantidad" tags={["Financials"]}>
  ### ¿Qué hay de nuevo?

  Mejoramos los **endpoints de la API de combustible** con campos adicionales para proporcionar detalles de transacción más completos:

  * **TransactionDate** → Ahora se incluye en todas las transacciones de combustible.
  * **Quantity** → Cada transacción incluye la cantidad comprada con valor y unidad de medida:

  ```json theme={null}
  "Quantity": {
    "Value": 7.799,
    "UnitOfMeasure": "Gallons"
  }
  ```

  Esto permite calcular con precisión el combustible total comprado y mejorar las métricas de los informes.

  <br />
</Update>

<Update label="August 21, 2025" description="Desglose granular de accesoriales: clientes, transportistas y conductores" tags={["Added", "Carriers", "Customers"]}>
  **Fecha de lanzamiento:** 21 de agosto de 2025

  ## ¿Qué hay de nuevo?

  Agregamos **desgloses detallados de accesoriales** a los endpoints `/loads` y `/trips`. En lugar de solo totales, cada accesorial se devuelve ahora como su propio registro, brindándote visibilidad total de los cargos.

  * **Soporte multi-entidad**: Los accesoriales ahora se rastrean para **clientes, transportistas, conductores y OwnerOperators**.
  * **Integración con EChecks**: Los accesoriales de conductor y OwnerOperator pueden incluir números de eCheck vinculados y montos.
  * **Lógica de liquidación actualizada**: `TotalPayable` ahora se calcula como `Linehaul + Accessorials – EChecks`.

  ## ¿Qué cambió?

  * **`/loads`** → Se agregó `CustomerAccessorialsDetails[]`.
  * **`/trips`** → Nuevos arreglos de detalle para:

    * `Carrier.AccessorialsDetails[]`
    * `Driver1.AccessorialsDetails[]` para conductor y OwnerOperator.
  * **Cada accesorial incluye**:

    * Predeterminado: `Id`, `Type`, `Total { Amount, Currency }`, `Rate { Amount, Currency }`, `RateType`, `Uom`, `Quantity`
    * Opcional: `IsPaid`, `ECheckNumber`, `StopId`
    * Auditoría: `CreatedAt`, `UpdatedAt`, `CreatedBy`, `UpdatedBy`
  * **EChecks** ahora se devuelven como parte de los datos del viaje cuando corresponde.
  * **Cargas/viajes cancelados** → No se devuelven detalles de accesoriales.
  * **Compatibilidad hacia atrás** → Los totales heredados siguen disponibles (`CustomerAccessorials`, `Carrier.Accessorials`, `Linehaul`, etc.), por lo que este cambio no es disruptivo.

  ### Ejemplo — Accesoriales

  ```json theme={null}
  {
    "Id": "acc-78901",
    "Type": "Layover Pay",
    "Total": { "Amount": 150.0, "Currency": 840 },
    "Rate": { "Amount": 75.0, "Currency": 840 },
    "RateType": "Time",
    "Uom": "Hour",
    "Quantity": 2.0,
    "ECheckNumber": "12345",
    "CreatedAt": "2024-07-11T14:30:00Z"
  }
  ```

  ## Endpoints afectados

  * `GET /api/p/v{version}/loads`
  * `POST /api/p/v{version}/loads/search`
  * `GET /api/p/v{version}/trips`
  * `POST /api/p/v{version}/trips/search`

  ## ¿Por qué?

  Esta mejora proporciona **datos de facturación granulares** para todas las partes involucradas en una carga o viaje, incluidos cargos al cliente, costos del transportista, pago al conductor y gastos de owner-operator. Con el seguimiento de eChecks y la lógica actualizada de `TotalPayable`, puedes reconciliar los pagos con mayor precisión mientras mantienes **compatibilidad total hacia atrás** para las integraciones existentes.
</Update>

<Update label="August 8, 2025" description="Nuevo campo de respuesta, LoadType, para distinguir entre cargas con y sin ingresos" tags={["Added", "Loads"]}>
  **Fecha de lanzamiento:** 7 de agosto de 2025

  **¿Qué hay de nuevo?**

  Hemos agregado un nuevo campo de respuesta, **`LoadType`**, para distinguir entre cargas con ingresos y sin ingresos.

  **¿Qué cambió?**

  * **`LoadType`** ahora aparece en los objetos de carga.
  * Valores devueltos: `"Revenue"` o `"Non-Revenue"`

  **Endpoints afectados:**

  * `GET  /api/p/{version}/loads`
  * `POST /api/p/{version}/loads/search`

  **¿Por qué?**

  Este campo facilita filtrar y reportar sobre cargas generadoras de ingresos frente a las que no generan ingresos directamente en tus integraciones de API.
</Update>

<Update label="August 7, 2025" description="Exposición de cargas y viajes eliminados en la API pública cuando `IncludeDeleted` es true" tags={["Added", "Trips", "Loads"]}>
  Fecha de lanzamiento: 7 de agosto de 2025

  **¿Qué hay de nuevo?**

  Hemos agregado un parámetro de solicitud opcional, **`IncludeDeleted`**, para que puedas controlar si las cargas y viajes eliminados aparecen en las respuestas de la API.

  **¿Qué cambió?**

  * Anteriormente, las cargas y viajes eliminados nunca se devolvían.
  * Ahora puedes incluir **`IncludeDeleted`** (booleano, opcional) en el cuerpo de tu solicitud:

    * `true` → devuelve registros activos y eliminados.
    * omitido o `false` → devuelve solo registros activos.
  * Cuando `IncludeDeleted: true`, cada registro devuelto incluye una bandera **`IsDeleted`**:

    * `"IsDeleted": true` para elementos eliminados
    * `"IsDeleted": false` para elementos activos
  * Cuando `IncludeDeleted` se omite o es `false`, **no** aparecen banderas `IsDeleted` (todos los registros son activos por definición).

  **Endpoints afectados:**

  * `POST /api/p/{version}/loads/search`
  * `POST /api/p/{version}/trips/search`

  **¿Por qué?**

  Esta mejora te da control directo sobre incluir o excluir registros eliminados a nivel de API, exponiendo datos eliminados solo cuando sea necesario.
</Update>

<Update label="June 24, 2025" description="📝 Power BI: nueva autenticación, paginación automática y más mejoras" tags={["Improved", "Authentication", "Documentation"]}>
  **Fecha de lanzamiento: junio de 2025**

  ***

  ### 🔐 **Nueva autenticación**

  * Ahora obtén el token de acceso mediante `auth.alvys.com/oauth/token` para mejorar la seguridad y el cumplimiento.
  * **El método de autenticación antiguo pronto será deshabilitado**; actualiza tus credenciales usando las nuevas instrucciones de configuración.

  ***

  ### 🔄 **Paginación automatizada**

  * Todas las consultas ahora gestionan la **paginación automáticamente**.
  * Los conjuntos de datos grandes se cargan por completo, sin registros faltantes ni ajustes manuales.
  * Un mecanismo de retardo integrado ayuda a evitar alcanzar los límites de tasa de la API durante las actualizaciones, mejorando la confiabilidad para grandes extracciones de datos.

  ***

  ### ↔️ **Expansión de datos anidados**

  * Las consultas de datos ahora **expanden automáticamente hasta 3 niveles** de campos anidados.
  * Todos los datos relevantes de la API son accesibles sin pasos manuales adicionales.

  ***

  ### 🗓️ **Conversión automática de tipos de campos**

  * Los campos clave, como fechas y números, ahora se convierten automáticamente a los tipos de datos correctos durante la importación (por ejemplo, columnas de fecha a datetime, montos a números).
  * Garantiza el filtrado, los cálculos y la visualización correctos en tus informes sin ajustes manuales.

  ***

  ### 📦 **Mejoras en los datos de cargas**

  * Las cargas se importan mediante dos consultas:

    * **Importación completa**
    * **Actualizaciones incrementales**
  * La **deduplicación automática** garantiza que solo se conserve la actualización más reciente de cada carga.

  ***

  ### 🧰 **Estructura de consulta consistente**

  * Todos los endpoints (Loads, Trips, Users, etc.) ahora utilizan un **patrón unificado de paginación y expansión**.
  * Hace que el modelo sea más fácil de entender, solucionar problemas y ampliar.

  ***

  ### 📊 **Nuevas funciones de DAX e informes**

  * Se agregaron varias fórmulas DAX básicas (por ejemplo, sumas, conteos o promedios simples) para ayudar a los usuarios a analizar rápidamente y familiarizarse con sus datos.
  * Se creó una tabla de informe resumen semanal de muestra: agrega métricas centrales por semana, lo que facilita detectar tendencias a lo largo del tiempo.
  * Estos ejemplos están pensados como punto de partida para tu propio análisis; siéntete libre de ajustarlos o ampliarlos según sea necesario.

  ***

  \u0001\u0001\u0001  ### 📘 **Onboarding mejorado**

  * Se incluyen **instrucciones de configuración paso a paso** para guiarte a través de la actualización de credenciales y la carga de datos. Puedes encontrar el enlace al archivo más reciente y una [guía rápida de onboarding aquí](/en/api/guides/power-bi-template-file-fast-setup-guide).

  ***

  *Si tienes preguntas o necesitas ayuda para migrar, consulta las instrucciones incluidas o contacta con tu equipo de soporte.*
</Update>

<Update label="June 17, 2025" description="Precisión mejorada de viajes para cargas divididas" tags={["Fixed", "Trips", "Loads"]}>
  Fecha de lanzamiento: 17 de junio de 2025

  **¿Qué hay de nuevo?**

  Para mejorar la claridad y eliminar la confusión en los reportes de viajes, hemos actualizado el comportamiento de los endpoints de Trips al manejar cargas divididas.

  **¿Qué cambió?**

  Cuando una carga se divide en sub-viajes, el viaje original (padre) ya no se devuelve a través de la API. Solo se incluyen los sub-viajes activos en la respuesta.

  Si una carga no ha sido dividida, el viaje original se devuelve como de costumbre.

  **Endpoints afectados:**

  `GET /api/p/version/trips`

  `POST /api/p/version/trips/search`

  **¿Por qué?**

  Anteriormente, tanto el viaje original (padre) como sus sub-viajes se devolvían a través de la API. Esto podía provocar duplicación de millaje, montos del transportista y otros valores en los informes, a menos que el viaje padre se excluyera manualmente.\
  Con esta actualización, solo se devuelven los sub-viajes cuando una carga se divide, lo que permite a los clientes calcular los totales (como millaje o montos del transportista) simplemente sumando todos los viajes devueltos.
  Este cambio mejora la precisión en cualquier informe que se base en datos a nivel de viaje.

  <br />

  > ❗️ Nota importante
  >
  > **Este cambio puede afectar las métricas en tus informes actuales**, como total de viajes, millaje total, tarifa total del transportista, entre otros, **a partir de hoy.**
  >
  > Si tu lógica de informes incluye filtros o scripts personalizados para excluir automáticamente el viaje original *(despachado)* cuando una carga se divide, esos filtros ahora pueden quedar obsoletos. Dado que el viaje original ya no se devuelve, continuar excluyéndolo puede provocar un subregistro.
  >
  > Por favor, revisa y actualiza cualquier lógica de informes personalizada en consecuencia para garantizar totales precisos en el futuro.
</Update>

<Update label="June 13, 2025" description="🔐 Nuevo endpoint de token con acceso granular a la API" tags={["Added", "Authentication"]}>
  **Fecha de lanzamiento:** 13 de junio de 2025

  ### **¿Qué hay de nuevo?**

  Hemos introducido mejoras en la forma en que se autoriza el acceso a la API para reforzar la seguridad y dar a los clientes un control más preciso sobre qué datos y acciones pueden acceder sus integraciones.

  ### **¿Qué cambió?**

  * Ahora se debe utilizar un nuevo endpoint de token para generar tokens de acceso:\
    `POST https://auth.alvys.com/oauth/token`
  * Los tokens ahora incluyen alcances de permisos (por ejemplo, `load:read, trip:create`) que definen a qué recursos y acciones puede acceder el cliente
  * La aplicación de acceso basado en alcances está habilitada para los tokens generados a través del nuevo endpoint; las solicitudes sin el alcance adecuado devolverán 403 Forbidden
  * El endpoint de token heredado `{tenant_id}` está en desuso y se cerrará el 31 de julio de 2025\
    (los tokens de este endpoint no incluyen alcances y por ahora se tratan como de solo lectura)

  ### **Cómo solicitar un token**

  Para solicitar un token, envía una solicitud `POST` al nuevo endpoint con este cuerpo JSON:

  ```json theme={null}
  {
    "client_id": "YOUR_CLIENT_ID",
    "client_secret": "YOUR_CLIENT_SECRET",
    "audience": "https://api.alvys.com/public/",
    "grant_type": "client_credentials"
  }
  ```

  <Tip>
    Al incluir un campo "scope" en el cuerpo de la solicitud de token, ten en cuenta:

    * El token devuelto **siempre incluirá todos los alcances** que se hayan otorgado a tu aplicación cliente, independientemente de lo que especifiques en el campo scope.
    * Por lo tanto, incluir un campo `scope ` en la solicitud **no anula ni limita el acceso** definido por tus permisos asignados en el token emitido.
    * El único efecto funcional de proporcionar un campo `scope` es que la solicitud de token fallará (no autorizada) si incluyes algún alcance que no se le haya otorgado a tu cliente.
    * Si se omite el campo `scope `, el token seguirá incluyendo **todos los alcances** otorgados a tu aplicación.
  </Tip>

  ### **Endpoints afectados:**

  * ✅ **Nuevo (requerido):** `POST https://auth.alvys.com/oauth/token`
  * 🛑 **Próximamente en desuso:** `POST /authentication/{tenant_id}/token` (se eliminará el **31 de julio de 2025**)

  <br />

  > ❗️ **Importante:**
  >
  > El endpoint de token heredado `POST /authentication/{tenant_id}/token` será **desactivado permanentemente el 31 de julio de 2025**. **Todas las integraciones que usen este flujo de autenticación deben actualizarse para utilizar el nuevo endpoint de token antes de esta fecha para evitar interrupciones.**
</Update>

<Update label="May 30, 2025 · 6:41 PM" description="Detalles de tarifa de transportista mejorados en los endpoints de Trips" tags={["Added", "Carriers", "Invoices"]}>
  **Fecha de lanzamiento**: 3 de junio de 2025

  **¿Qué hay de nuevo?**

  El objeto Carrier en los endpoints de Trips ahora incluye campos adicionales de desglose de pagos:

  * `Linehaul` — Costo base de transporte.
  * `Accessorials` — Cargos adicionales (por ejemplo, recargos de combustible, detención).
  * `TotalPayable` — Monto total a pagar al transportista.

  Endpoints actualizados:

  `GET /api/p/v1/trips`

  `POST /api/p/v1/trips/search`

  **¿Por qué?**\
  Estos campos adicionales proporcionan una vista más detallada de los pagos al transportista, ayudando a los clientes con una reconciliación y reportes más precisos. Asegura la consistencia con los datos financieros vistos en la interfaz de Alvys y mejora la transparencia financiera en los reportes.

  > ❗️ **Importante:**  El campo Rate en el objeto Carrier quedará en desuso en una versión futura.
  >
  > **Recomendamos actualizar los reportes e integraciones para utilizar los nuevos campos `Linehaul`, `Accessorials` y `TotalPayable `.**
  >
  > **Este cambio no ocurrirá de inmediato: habrá un período de transición y proporcionaremos un aviso previo antes de que se elimine el campo.**
  >
  > Por favor, revisa tu uso actual y planifica las actualizaciones en consecuencia para garantizar una transición fluida.
</Update>

<Update label="May 30, 2025 · 6:36 PM" description="Endpoints de transportistas agregados a la API pública" tags={["Added", "Carriers"]}>
  **Fecha de lanzamiento**: 3 de junio de 2025

  **¿Qué hay de nuevo?**

  Se han agregado dos nuevos endpoints a la API pública para transportistas y subsidiarias:

  `GET /api/p/v1/carriers/'{id}'` — Obtiene información detallada del transportista o subsidiaria por ID.

  `POST /api/p/v1/carriers/search` — Busca transportistas o subsidiarias utilizando filtros como Status, números MC, números DOT o IDs específicos.

  **¿Por qué?**\
  Estos nuevos endpoints mejoran la accesibilidad y precisión de los datos, permitiendo a los clientes obtener solo los datos de transportista que necesitan. Esta mejora respalda un mejor rendimiento, elimina extracciones masivas innecesarias y alinea la API pública con las necesidades operativas de los clientes.
</Update>

<Update label="May 22, 2025" description="Mejora de visibilidad del estado del conductor" tags={["Added", "Visibility", "Drivers"]}>
  **Fecha de lanzamiento:** 22 de mayo de 2025

  **¿Qué se mejoró?**

  Hemos actualizado los endpoints de conductor en la API pública para incluir un campo `isActive`, ayudando a los sistemas externos a determinar fácilmente si un conductor está actualmente activo según su estado operativo.

  **Campo agregado:**

  `isActive` – Indica si el conductor está actualmente activo.

  El valor de `isActive` es:

  * ✅ `true` para activo
  * ❌ `false` para inactivo.

  **¿Por qué?**

  Anteriormente, los consumidores de la API debían interpretar cadenas de estado sin procesar para determinar la actividad. Ahora, el sistema realiza ese trabajo internamente y devuelve un valor claro y fácil de usar, reduciendo la complejidad y ayudando a los equipos a filtrar o mostrar la actividad del conductor de manera más confiable.
</Update>

<Update label="May 14, 2025" description="Actualización de la API pública – Marcas de tiempo precisas de recogida y entrega" tags={["Fixed"]}>
  **Fecha de lanzamiento:** 14 de mayo de 2025

  Hemos corregido un problema en el que las marcas de tiempo reales de recogida y entrega mostraban valores incorrectos en la API pública.

  ✅ Qué se corrigió

  `ScheduledPickupAt` y `ScheduledDeliveryAt` reflejan el horario planificado

  `PickupDate` y `DeliveryDate` muestran la marca de tiempo real de recogida y entrega

  Endpoints afectados

  GET /api/p/`v{version}`/loads

  POST /api/p/`v{version}`/loads/search

  Nota: No se requiere ninguna acción, tus integraciones ahora devolverán los valores correctos automáticamente.
</Update>

<Update label="April 18, 2025" description="Endpoints de registros de mantenimiento en la Public API" tags={["Added", "Maintenance"]}>
  ### ¿Qué hay de nuevo?

  Los registros de mantenimiento de activos ahora son legibles a través de la Public API, lo que permite a las plataformas de mantenimiento de flotas (p. ej. FleetRock) y herramientas de informes sincronizar el historial de mantenimiento de camiones y remolques.

  ### ¿Qué cambió?

  Anteriormente, los registros de mantenimiento solo eran visibles dentro de la plataforma Alvys.

  Ahora, la Public API incluye:

  ```http theme={null}
  GET  /api/p/v{version}/maintenance/{id}
  POST /api/p/v{version}/maintenance/search
  ```

  * **Get maintenance record** — recupera un único registro por id.
  * **Search maintenance records** — busca y pagina registros.

  ### El cuerpo de respuesta incluye

  * Core: `Id`, `PO`, `Reference`, `Description`, `Comments`
  * Classification: `Category`
  * Asset: `RelatedAsset` (el camión o remolque al que pertenece el registro)
  * Financial: `Amount` (valor + moneda)
  * Shop: detalles de `RepairShop`
  * Scheduling: `Reminders`
  * Audit: `CreatedAt`, `CreatedBy`, `ModifiedAt`, `ModifiedBy`

  ### ¿Por qué?

  El gasto y el historial de mantenimiento viven en la intersección de operaciones y contabilidad. Exponer estos registros permite que los proveedores de mantenimiento y las herramientas de análisis se mantengan sincronizados con Alvys sin exportaciones manuales.
</Update>

<Update label="April 16, 2025" description="🔐 Mejora del endpoint de token – Soporte JSON agregado y validación más estricta aplicada" tags={["Added", "Authentication"]}>
  **Fecha de lanzamiento:** 16 de abril de 2025

  **¿Qué hay de nuevo?**\
  El endpoint de autenticación `/token` ahora admite solicitudes con Content-Type: `application/json`, además del soporte existente para `application/x-www-form-urlencoded`.

  Este cambio se aplica a:

  POST /api/authentication/`{tenant_id}`/token

  **¿Por qué?**\
  Admitir solicitudes en formato JSON mejora la experiencia del desarrollador al alinearse con los estándares modernos de integración. Permite a los clientes elegir el formato que mejor se adapte a su arquitectura y garantiza la consistencia entre las llamadas a la API.

  <Warning>
    **Importante:** El endpoint `/api/authentication/{tenant_id}/token` ahora aplica **una validación de tipo de contenido más estricta**.\
    Solo se admiten `application/json` y `application/x-www-form-urlencoded`.
    Las solicitudes que utilicen otros formatos devolverán un error **415 Unsupported Media Type**.
  </Warning>
</Update>

<Update label="March 26, 2025" description="Actualización del endpoint de Trips: campo `ReleasedAt` agregado" tags={["Added", "Trips"]}>
  **Fecha de lanzamiento:** 27 de marzo de 2025

  ¿Qué hay de nuevo?\
  Se agregó el campo `ReleasedAt` a los siguientes endpoints de Trips de la API pública:

  `GET /api/p/v{version}/trips`\
  `POST /api/p/v{version}/trips/search`

  Este campo indica la marca de tiempo en la que la carga fue marcada como "Released".

  ¿Por qué?\
  Exponer el campo `ReleasedAt` permite a los clientes crear informes más personalizables y precisos. Garantiza la consistencia con los datos internos y proporciona una mejor visibilidad de los plazos de liberación de cargas.
</Update>

<Update label="March 25, 2025" description="Exposición del campo CarrierPaymentOnHold en los endpoints de Trips" tags={["Added", "Carriers", "Invoices"]}>
  **Fecha de lanzamiento:** 25 de marzo de 2025

  ¿Qué hay de nuevo?

  Se expuso el campo `CarrierPaymentOnHold` en los siguientes endpoints de Trips de la API pública:

  `GET   /api/p/v1/trips`

  `POST   /api/p/v1/trips/search`

  Este campo indica si el pago de un transportista está actualmente en espera.

  **¿Por qué?**

  Anteriormente, los usuarios de la API no podían determinar si el pago de un transportista estaba en espera al recuperar los datos de viaje, lo que creaba una brecha de visibilidad. Al exponer el campo `CarrierPaymentOnHold` en los endpoints de Trips, los usuarios ahora pueden acceder programáticamente a este estado crítico para respaldar la automatización, los flujos de trabajo financieros y las decisiones operativas.
</Update>

<Update label="March 3, 2025" description="Nuevo endpoint de preferencias de despacho" tags={["Added", "Dispatch"]}>
  **Fecha de lanzamiento:** 28 de febrero de 2025

  **¿Qué hay de nuevo?**

  Se agregó un nuevo endpoint `/api/p/v{version}/dispatchpreferences/search` para recuperar las preferencias de despacho basadas en filtros como despachador, conductor, camión y remolque o rango de fechas.

  **¿Por qué?**

  Este endpoint se introdujo para mejorar el seguimiento y la gestión de las preferencias de despacho, permitiendo operaciones más eficientes.
</Update>

<Update label="February 6, 2025 · 8:55 AM" description="Mejoras en las Tarifas de Carga" tags={["Improved", "Loads"]}>
  **Fecha de lanzamiento:** 01 de febrero de 2025

  **¿Qué se mejoró?**

  Hemos actualizado el endpoint de Load para incluir desgloses financieros adicionales, haciendo que los cálculos de tarifas sean más transparentes y detallados.

  **Campos agregados:**

  * `linehaul `– Costo base de transporte.
  * `fuelSurcharge `– Ajustes por costo de combustible.
  * `customerAccessorials` – Cargos adicionales como detención o tarifas de lumper.

  ¿Por qué?

  Anteriormente, los detalles de costos carecían de granularidad, dificultando el seguimiento de los componentes financieros. Estas actualizaciones proporcionan una visibilidad más clara sobre los precios de las cargas, ayudando a las empresas a optimizar la gestión de sus costos.
</Update>

<Update label="February 6, 2025 · 8:48 AM" description="Exposición de Endpoints de Eventos de Activos" tags={["Added"]}>
  **Fecha de lanzamiento:** 01 de febrero de 2025

  **¿Qué hay de nuevo?**

  Hemos agregado tres nuevos endpoints a la Public API para proporcionar actualizaciones de eventos sobre camión, conductor y remolque, mejorando el seguimiento y la visibilidad operativa.

  POST /api/p/v\{version}/drivers/events/search – Recupera el historial de eventos relacionados con conductores.

  POST /api/p/v\{version}/trailers/events/search – Obtiene eventos relacionados con remolques.

  POST /api/p/v\{version}/trucks/events/search – Accede al historial de eventos de camiones.

  **¿Por qué?**

  Estos cambios mejoran la capacidad de la API para automatizar el seguimiento de eventos de activos, mejorar la precisión de los datos y agilizar los flujos de trabajo para una mejor gestión de recursos.
</Update>

<Update label="December 13, 2024 · 6:50 PM" description="Límite de Búsqueda de LoadNumber Actualizado" tags={["Improved", "Loads"]}>
  **Fecha de lanzamiento**: 16 de diciembre de 2024

  **¿Qué hay de nuevo?**:

  * **Límite aumentado**: El número máximo de cargas permitidas en el cuerpo de la solicitud de búsqueda ha aumentado de **50** a **150**.
    * **Impacto**: Los usuarios ahora pueden incluir más IDs de carga en una sola operación de solicitud de búsqueda.
    * **Manejo de errores**: Las solicitudes que superen los 150 IDs de carga devolverán un mensaje de error.
</Update>

<Update label="December 13, 2024 · 6:46 PM" description="Mejora del Endpoint de Trips: DispatcherId Agregado" tags={["Added", "Trips", "Dispatch"]}>
  **Fecha de lanzamiento**: 13 de diciembre de 2024

  **¿Qué hay de nuevo?**:

  * **Campo DispatcherId**: El campo `DispatcherId` ahora se incluye en el cuerpo de respuesta de todos los endpoints de trips.
    * **Propósito**: Proporciona el identificador único del despachador asignado al viaje para mejorar el seguimiento de datos y la integración.
    * **Beneficios**: Mejora la gestión de viajes y la generación de informes al hacer que los datos del despachador sean más accesibles a través de la API.
</Update>

<Update label="November 11, 2024" description="Nuevos Endpoints para la Visibility Public API" tags={["Added", "Visibility"]}>
  #### **Fecha de lanzamiento**: 11 de noviembre de 2024

  ***

  ### **¿Qué hay de nuevo?**

  1. **Endpoints de la Visibility Public API**:
     * Introduce endpoints para rastrear ubicaciones de activos y recibir actualizaciones de eventos en tiempo real.

  2. **Descripción general de los endpoints**:

     * **Visibilidad entrante (Inbound Visibility)**:
       * **GET** `/api/p/v{version}/visibility/inbound/{loadNumber}/history`: Recupera el historial de actualizaciones de ubicación para un número de carga específico.

     * **Visibilidad saliente (Outbound Visibility)**:
       * **GET** `/api/p/v{version}/visibility/outbound/{loadNumber}/history`: Recupera el historial de actualizaciones de eventos enviados para un número de carga específico.
       * **POST** `/api/p/v{version}/visibility/outbound/errors`: Busca y reenvía manualmente las actualizaciones fallidas usando un filtro de rango de tiempo.

  ***

  ### **Uso**

  #### **Ejemplo de Visibilidad Entrante**

  ```json theme={null}
  GET /api/p/v{version}/visibility/inbound/{{loadNumber}}/history
  ```

  #### **Ejemplos de Visibilidad Saliente**

  ```json theme={null}
  GET /api/p/v{version}/visibility/outbound/{{loadNumber}}/history
  ```

  #### **Buscar actualizaciones fallidas**:

  ```json theme={null}
  POST /api/p/v{version}/visibility/outbound/errors
  {
    "page": 0,
    "pageSize": 10,
    "timeRange": {
      "start": "2024-11-05T16:58:54.450Z",
      "end": "2024-11-11T16:58:54.450Z"
    }
  }
  ```

  ### **Recursos adicionales**

  * [Documentación de la API](/en/api/reference/visibility/get-inbound-visibility-history)
  * [Colección de Postman](https://www.postman.com/alvys-public-api-team/alvys-public-api/collection/2p0o9wj/alvys-public-api-collection)

  ***

  ### **Notas importantes**

  ⚠️ **Configuración para la integración EDI**:

  * Todas las configuraciones relacionadas con EDI deben realizarse dentro de la plataforma. Contacta al equipo de soporte si necesitas asistencia.

  ***
</Update>

<Update label="November 8, 2024 · 1:11 PM" description="Actualización para el campo Customer Rate Details" tags={["Improved", "Customers"]}>
  #### **Fecha de lanzamiento**: 08 de noviembre de 2024

  ***

  ### **¿Qué hay de nuevo?**

  1. **Actualización del campo`customerRate.amount`**:
     * **Cambio**: El campo `customerRate.amount` ahora incluye lo siguiente:
       * `CustomerLineHaul`
       * `FuelSurcharge`
       * `CustomerAccessorials`
     * **Impacto**: Esto garantiza la alineación con el total facturable al cliente mostrado en la UI, mejorando la precisión para la facturación y los informes de ingresos.

  2. **Propósito**:
     * Mejora la claridad y precisión de los cargos de tarifa del cliente.

  ***

  ### **Uso**

  * El campo `customerRate.amount` ahora refleja la tarifa total del cliente, incorporando: Linehaul, Fuel Surcharge, Accessorials).

  **Ejemplo de cálculo**:

  ```json theme={null}
  "CustomerRate": {
                  "Amount": 5168.0,
                  "Currency": 840
              },
  ```

  ***

  ### **Endpoints afectados**

  * **GET** `/api/p/v{version}/loads`: [Ver documentación](/en/api/reference/loads/get-load)
  * **POST** `/api/p/v{version}/loads/search`: [Ver documentación](/en/api/reference/loads/search-loads)

  ***

  ### **Nota importante**

  ⚠️ **Si dependías del valor anterior de`customerRate.amount` para informes de ingresos, revisa tu integración. Este cambio corrige el cálculo para incluir Customer Accessorials, que anteriormente se excluían.**

  ***
</Update>

<Update label="November 8, 2024 · 1:07 PM" description="Nuevos Endpoints para la Gestión de Datos de Clientes" tags={["Added", "Customers"]}>
  #### **Fecha de lanzamiento**: 11 de noviembre de 2024

  ***

  ### **¿Qué hay de nuevo?**

  1. **Nuevos endpoints GET y POST introducidos**:

     * **Endpoint GET**:

       * **`/api/p/v{version}/customers`**: Recupera perfiles detallados de clientes, incluida la información de contacto y los datos asociados, por `id` o `companyNumber`.

       **Ejemplo de solicitud**:

       ```json theme={null}
       GET /api/p/v{version}/customers?id=12345
       //or
       //GET /api/p/v{version}/customers?companyNumber=12345
       ```

     * **Endpoint POST**:

       * **`/api/p/v{version}/customers/search`**: Admite búsquedas filtradas avanzadas de registros de clientes por estado o rango de fechas. Incluye paginación para un acceso optimizado a los datos.

       **Ejemplo de solicitud**:

       ```json theme={null}
       POST /api/p/v{version}/customers/search
       {
         "page": 0,
         "pageSize": 100,
         "statuses": [
           "Active"
         ],
         "createdDateRange": {
       //     "start": "2024-11-08T19:38:34.529Z",
       //     "end": "2024-11-08T19:38:34.529Z"
         }
       }
       ```

  ***

  ### **Propósito**

  * Proporciona flexibilidad para recuperar y buscar datos de clientes.
  * Habilita flujos de trabajo optimizados para integración, automatización e informes.

  ***

  ### **Recursos adicionales:**

  * [Documentación de la API](/en/api/reference/customers/list-customers)
  * [Colección de Postman](https://app.getpostman.com/run-collection/39138316-54c493c3-15e5-4fd7-a651-6e45b308548f?action=collection%2Ffork\&source=rip_markdown\&collection-url=entityId%3D39138316-54c493c3-15e5-4fd7-a651-6e45b308548f%26entityType%3Dcollection%26workspaceId%3Dc0255544-5964-4c52-9d24-05b30a9b021c)

  ***
</Update>

<Update label="October 18, 2024 · 11:49 AM" description="Mejoras en la Gestión de Cargas con Nuevos Campos de Asignación" tags={["Added", "Loads"]}>
  ### **¿Qué hay de nuevo?**

  1. **Nuevos campos agregados al cuerpo de respuesta de los endpoints de Load**:
     * **`customerServiceRepId`**: Representante de servicio al cliente asignado a la carga.
     * **`customerSalesAgentId`**: Agente de ventas del cliente responsable de la carga.
     * **`customerSalesManagerId`**: Gerente de ventas del cliente asignado a la carga.
     * **`customerLoadPlannerId`**: Gerente de ventas del cliente asignado a la carga.
     * **`carrierSalesAgentId`**: Agente de ventas de transportistas asignado a la carga, que permite a los clientes atribuir crédito y calcular comisiones por asegurar al transportista.

  2. **Propósito**:
     * Mejora la transparencia en las asignaciones de cargas.
     * Optimiza los procesos de gestión de tenders y seguimiento de cargas.

  ***
</Update>

<Update label="October 18, 2024 · 5:43 AM" description="Inclusión de `UpdatedAt` y `UpdatedBy` en los Endpoints de Load y Trip" tags={["Added", "Trips", "Loads"]}>
  #### **Fecha de lanzamiento**: 18 de octubre de 2024

  ***

  ### **¿Qué hay de nuevo?**

  \u0001\u0001\u0001

  1. **Nuevos campos agregados a los endpoints de Load y Trip**:

     * **`UpdatedAt`**: Marca de tiempo de la última modificación.
     * **`UpdatedBy`**: ID de usuario responsable de la última actualización.

  2. **Nuevos parámetros agregados al cuerpo de búsqueda de Load y Trip**:
     * `UpdatedAtRange`: Buscar por marcas de tiempo de actualización usando fecha `start` o `end`.
     * `UpdatedBy`: Buscar por el usuario que realizó las actualizaciones.

  ```json theme={null}
  {
      "updatedAtRange": {
          "start": "2024-10-18T04:38:53.470Z",
          "end": "2024-10-19T04:38:53.470Z"
      },
      "updatedBy": "user123"
  }
  ```

  3. **Parámetros condicionalmente obligatorios**\
     Debe proporcionarse al menos **un parámetro de búsqueda** de la lista de parámetros condicionalmente obligatorios. Si no se incluye ningún parámetro, se devolverá el siguiente mensaje de error:

  ```json theme={null}
  {
      "Status": [
          "At least one search parameter must be provided"
      ],
      "PONumbers": [
          "At least one search parameter must be provided"
      ],
      "UpdatedBy": [
          "At least one search parameter must be provided"
      ],
      "CustomerId": [
          "At least one search parameter must be provided"
      ],
      "LoadNumbers": [
          "At least one search parameter must be provided"
      ],
      "OrderNumbers": [
          "At least one search parameter must be provided"
      ]
  }
  ```
</Update>

<Update label="July 5, 2024" description="Oferta Inicial de la Public API" tags={["Added"]}>
  ¡Nos complace anunciar la oferta inicial de la Alvys Public API! Este lanzamiento marca una nueva era de integración y personalización para nuestra plataforma.

  Aspectos destacados:

  * **Lanzamiento de la Public API**: Nuestra Public API ya está disponible, brindando a los desarrolladores acceso seguro y flexible a las funcionalidades principales de Alvys.
  * **Documentación integral**: Hay guías y recursos extensos disponibles para facilitar una integración e implementación fluidas.
  * **Características clave**: La API incluye endpoints para usuarios, camiones, remolques, conductores, cargas y viajes, y más, diseñados para permitir una fácil extracción de datos de Alvys.

  *Nota: Esta es la versión inicial de nuestra Public API, y estamos comprometidos a ampliar y mejorar continuamente sus capacidades. Los comentarios y sugerencias son bienvenidos mientras refinamos y hacemos crecer nuestras ofertas.*

  ¡Mantente atento a más actualizaciones y funciones! 🚀
</Update>
