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

# Carga en lote de activos

> Actualiza hasta 100 activos en una llamada: es «el `PATCH` de a 100». Cada entrada
identifica un activo por `id`, o por `idField` + `idValue` con las mismas reglas que el
parámetro `idField` (`plate`, `name` o el nombre interno de un campo con Valor único), y trae
en `data` el mismo cuerpo parcial que `PATCH /api/assets/{id}`: misma validación, misma mezcla
de `customFields` por clave y mismas reglas de obligatorio y Valor único. No crea activos.

**Resultado por fila.** Responde 200 con un resultado por entrada, en el mismo orden
(`index`), y un resumen. Una fila que falla no detiene a las demás:
- `updated`: se actualizó (o, con `dryRun`, se actualizaría).
- `notFound`: ningún activo de la empresa coincide (404 `ASSET_NOT_FOUND`).
- `ambiguous`: más de un activo coincide con `idField` (`details.assets`).
- `invalid`: la entrada o sus datos no son válidos (sin identificador, `idField` no admitido,
  tipo, regla, clave desconocida u obligatorio vaciado; `details` como en el `PATCH`).
- `conflict`: un valor único ya lo tiene otro activo (`details.asset`).

Las filas se procesan en orden y de a una: un valor único repetido dentro del lote falla en
la segunda fila que lo trae. Para reintentar, reenviá solo las filas que fallaron.

**`dryRun: true`** valida y resuelve todas las filas sin escribir nada (ni activos, ni
Registro de actividades) y devuelve el mismo resultado por fila que tendría la ejecución
real, incluidos los valores únicos repetidos contra lo guardado y dentro del lote.

Responde 400 solo si la petición en sí es inválida: más de 100 entradas, ninguna, un `id`
mal formado o una forma incorrecta. Cada fila actualizada registra su propio
`asset_updated` en el Registro de actividades con el canal de la escritura; no hay evento de
lote.

**Permisos requeridos:** `access_fleet_assets`




## OpenAPI

````yaml /openapi.json post /api/assets/batch/update
openapi: 3.0.0
info:
  title: UGPS Atlas API
  version: 1.0.0
  description: >-
    Documentación de la API REST principal de UGPS Atlas (plataforma de rastreo
    GPS)
servers:
  - url: https://api.ugps.io
    description: Servidor de producción
security:
  - bearerAuth: []
  - cookieAuth: []
tags:
  - name: Auth - Autenticación
    description: Operaciones de autenticación
  - name: Usuarios - Usuarios
    description: Operaciones relacionadas con usuarios
  - name: Usuarios - Roles
    description: Operaciones relacionadas con roles
  - name: Usuarios - Permisos
    description: Operaciones relacionadas con permisos
  - name: Activos - Assets
    description: Operaciones relacionadas con activos
  - name: Activos - Tipos
    description: Operaciones relacionadas con tipos de activos
  - name: Activos - Grupos
    description: Operaciones relacionadas con grupos de activos
  - name: Activos - Campos personalizados
    description: >-
      Campos propios que cada empresa define para sus activos (nombre interno,
      tipo, reglas y opciones)
  - name: Activos - Grupos de campos
    description: Grupos que ordenan los campos personalizados de la empresa
  - name: Activos - Vehículos
    description: Operaciones relacionadas con tipos de vehículos
  - name: Activos - QR
    description: >-
      QR del activo (identidad escaneable del activo): resolver, stickers,
      reemplazo e historial
  - name: Tracking - Trackers
    description: Operaciones relacionadas con trackers
  - name: Tracking - Viajes
    description: Operaciones relacionadas con viajes y paradas
  - name: Tracking - Geocercas
    description: Operaciones relacionadas con geocercas
  - name: Alertas - Alertas
    description: Operaciones relacionadas con alertas
  - name: Alertas - Disparadores
    description: Operaciones relacionadas con disparadores de alertas
  - name: Alertas - Notificaciones
    description: Operaciones relacionadas con notificaciones
  - name: Clientes - Clientes
    description: Operaciones relacionadas con clientes
  - name: Clientes - Restricciones
    description: Operaciones relacionadas con restricciones
  - name: Integraciones - Flespi
    description: Operaciones relacionadas con Flespi
  - name: Otros - Conductores
    description: Operaciones relacionadas con conductores
  - name: Formularios dinámicos
    description: Plantillas de formulario propias de Atlas, asignables a activos
  - name: Inspecciones
    description: >-
      Inspecciones de activos enviadas desde la app al escanear el QR, con
      resultado apta / no apta
  - name: Otros - Capas
    description: Operaciones relacionadas con capas
  - name: User Tracker Access
    description: Operaciones de acceso personalizado a trackers por usuario
  - name: Reportes - Historial de Posiciones
    description: Estadísticas y detalle de posiciones GPS por activo
  - name: Reportes - Excesos de Velocidad
    description: Reportes de excesos de velocidad por tracker
  - name: Reportes - Ralentí
    description: Reportes de ralentí (motor encendido sin movimiento) por tracker
  - name: Reportes - Horas de Trabajo
    description: >-
      Reportes de horas de trabajo (conducción + paradas dentro de horario
      laboral) por tracker
  - name: Reportes - Última Actividad
    description: Reporte de estado de comunicación y última posición de activos
  - name: Reportes - Reportes Programados
    description: Gestión de reportes programados (CRUD)
  - name: Device Health
    description: Operaciones de salud de dispositivos del cliente
  - name: Activity Log
    description: Registro de actividad del cliente
  - name: Work - Importaciones
    description: Operaciones de importación de datos
  - name: Work - Plantillas
    description: Operaciones de plantillas de importación
  - name: Cargo - Transportistas
    description: Gestión de transportistas
  - name: Cargo - Pedidos
    description: Gestión de pedidos de carga
  - name: Cargo - Monitoreo
    description: Monitoreo en vivo de carga y transporte
  - name: Integraciones - Navixy
    description: Integración con plataforma Navixy
  - name: Mantenimiento - Dashboard
    description: Dashboard y métricas generales de mantenimiento
  - name: Mantenimiento - Proveedores
    description: Gestión de proveedores de servicio
  - name: Mantenimiento - Estado
    description: Estado de mantenimiento de activos
  - name: Mantenimiento - Perfiles
    description: Perfiles de mantenimiento por activo
  - name: Mantenimiento - Fallas
    description: Gestión de fallas activas
  - name: Mantenimiento - DVIR
    description: Driver Vehicle Inspection Reports
  - name: Mantenimiento - Defectos
    description: Gestión de defectos detectados
  - name: Mantenimiento - Programaciones
    description: Programación de mantenimientos preventivos
  - name: Mantenimiento - Próximos
    description: Ítems de mantenimiento próximos
  - name: Mantenimiento - Órdenes de Trabajo
    description: Gestión de órdenes de trabajo
  - name: Mantenimiento - Registros de Servicio
    description: Registros históricos de servicios realizados
  - name: Mantenimiento - Problemas
    description: Gestión de problemas de mantenimiento
  - name: Mantenimiento - Tareas de Servicio
    description: Tareas específicas dentro de órdenes de trabajo
  - name: Mantenimiento - Inventario
    description: Gestión de partes, ubicaciones y stock
  - name: Mantenimiento - Costos
    description: Gestión y agregación de costos de mantenimiento
  - name: Trabajo - Tareas
    description: Gestión de tareas, tareas recurrentes, rutas y operaciones en lote
  - name: Trabajo - Empleados
    description: Gestión de empleados, departamentos y sus catálogos (tags, trackers)
  - name: Otros - Lugares
    description: Gestión de lugares (places) del cliente
  - name: Cargo - Activos
    description: Disponibilidad de activos de carga
  - name: Cargo - Ubicaciones
    description: Gestión de ubicaciones de carga
  - name: Cargo - Rendimiento
    description: Métricas de rendimiento de pedidos de carga
  - name: Reportes - Check-ins
    description: Reporte de check-ins de tareas
  - name: Reportes - Utilización
    description: Reporte de utilización de activos
  - name: Reportes - Visitas por Geocercas
    description: Reporte de visitas a geocercas
  - name: Reportes - Visitas por Trackers
    description: Reporte de visitas por tracker/activo
  - name: Reportes - Progreso de Geozonas
    description: Reporte de progreso de cobertura de geozonas (agricultura)
  - name: Reportes - Temperatura
    description: Reporte de temperatura por activo
  - name: Reportes - Exportación
    description: Exportación de reportes a archivo
  - name: Público - Business Time
    description: Reloj de servidor (endpoint público, sin autenticación)
  - name: Formularios
    description: Definiciones y envíos de formularios de la app
  - name: Sistema
    description: Endpoints de salud del servicio (liveness/readiness), sin autenticación
  - name: Facturación
    description: >-
      Portal del cliente — facturas publicadas de la empresa (proyección de
      Raúl)
  - name: Tienda de módulos
    description: >-
      Catálogo de módulos y productos UGPS con el estado de cada uno para el
      usuario
  - name: Soporte
    description: Portal del cliente — tickets de soporte de la empresa (proyección de Raúl)
  - name: Asistente
    description: Historial de conversaciones del Asistente de Atlas (spec
paths:
  /api/assets/batch/update:
    post:
      tags:
        - Activos - Assets
      summary: Carga en lote de activos
      description: >
        Actualiza hasta 100 activos en una llamada: es «el `PATCH` de a 100».
        Cada entrada

        identifica un activo por `id`, o por `idField` + `idValue` con las
        mismas reglas que el

        parámetro `idField` (`plate`, `name` o el nombre interno de un campo con
        Valor único), y trae

        en `data` el mismo cuerpo parcial que `PATCH /api/assets/{id}`: misma
        validación, misma mezcla

        de `customFields` por clave y mismas reglas de obligatorio y Valor
        único. No crea activos.


        **Resultado por fila.** Responde 200 con un resultado por entrada, en el
        mismo orden

        (`index`), y un resumen. Una fila que falla no detiene a las demás:

        - `updated`: se actualizó (o, con `dryRun`, se actualizaría).

        - `notFound`: ningún activo de la empresa coincide (404
        `ASSET_NOT_FOUND`).

        - `ambiguous`: más de un activo coincide con `idField`
        (`details.assets`).

        - `invalid`: la entrada o sus datos no son válidos (sin identificador,
        `idField` no admitido,
          tipo, regla, clave desconocida u obligatorio vaciado; `details` como en el `PATCH`).
        - `conflict`: un valor único ya lo tiene otro activo (`details.asset`).


        Las filas se procesan en orden y de a una: un valor único repetido
        dentro del lote falla en

        la segunda fila que lo trae. Para reintentar, reenviá solo las filas que
        fallaron.


        **`dryRun: true`** valida y resuelve todas las filas sin escribir nada
        (ni activos, ni

        Registro de actividades) y devuelve el mismo resultado por fila que
        tendría la ejecución

        real, incluidos los valores únicos repetidos contra lo guardado y dentro
        del lote.


        Responde 400 solo si la petición en sí es inválida: más de 100 entradas,
        ninguna, un `id`

        mal formado o una forma incorrecta. Cada fila actualizada registra su
        propio

        `asset_updated` en el Registro de actividades con el canal de la
        escritura; no hay evento de

        lote.


        **Permisos requeridos:** `access_fleet_assets`
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - entries
              properties:
                dryRun:
                  type: boolean
                  default: false
                  description: Valida todas las filas sin escribir nada
                entries:
                  type: array
                  minItems: 1
                  maxItems: 100
                  items:
                    type: object
                    description: >
                      Un activo a actualizar: por `id`, o por `idField` +
                      `idValue` (uno de los dos). Una entrada

                      sin identificador sale como fila `invalid`.
                    required:
                      - data
                    properties:
                      id:
                        type: string
                        pattern: ^[a-fA-F0-9]{24}$
                        description: Id del activo
                        example: 6650f1a2c9d84e0012345678
                      idField:
                        type: string
                        description: >-
                          `plate`, `name` o el nombre interno de un campo con
                          Valor único
                        example: codigo_de_inventario
                      idValue:
                        type: string
                        description: >-
                          Valor de `idField` (texto sin distinguir mayúsculas ni
                          tildes)
                        example: ASM-001
                      data:
                        description: >
                          Cuerpo del `PATCH` parcial: los mismos campos del
                          activo, todos opcionales (también `name`

                          y `assetTypeId`), con las mismas reglas que el `PUT`.
                          Solo cambia lo que se envía;

                          `customFields` se mezcla por clave. Debe traer al
                          menos un campo.
                        allOf:
                          - type: object
                            properties:
                              kind:
                                type: string
                                enum:
                                  - vehicle
                                  - generic
                                description: >-
                                  Familia canonica del activo. Se rellena de
                                  forma compatible con tipos antiguos.
                              name:
                                type: string
                              icon:
                                type: object
                                properties:
                                  id:
                                    type: string
                                  color:
                                    type: string
                                    description: 'Formato hexadecimal (#RRGGBB o #RGB)'
                                    pattern: ^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$
                              mainTrackerId:
                                type: number
                              trackers:
                                type: array
                                items:
                                  type: object
                                  properties:
                                    id:
                                      type: number
                                    platform:
                                      type: string
                              plate:
                                type: string
                              vehicleTypeId:
                                type: string
                                description: >-
                                  ID del tipo de vehículo asociado al activo
                                  (opcional)
                              assetTypeId:
                                type: string
                              model:
                                type: string
                                description: Modelo del activo (opcional)
                              year:
                                type: number
                              color:
                                type: string
                                description: Color del activo (opcional)
                              make:
                                type: string
                              chassis:
                                type: string
                                description: Número de chasis del activo (opcional)
                              motor:
                                type: string
                                description: Número de motor del activo (opcional)
                              fuel:
                                type: string
                                description: Tipo de combustible del activo (opcional)
                              kilometer:
                                type: number
                                description: Kilometraje del activo (opcional)
                              technicalInspection:
                                type: object
                                description: >
                                  Revisión técnica del vehículo (opcional). La
                                  puebla la consulta vehicular

                                  por patente y también se puede editar a mano.
                                  Solo aplica a activos de

                                  kind `vehicle`: en los `generic` se limpia.
                                properties:
                                  date:
                                    type: string
                                    format: date
                                    description: >-
                                      Fecha en que se realizó la revisión, no su
                                      vencimiento
                                  result:
                                    type: string
                                    description: >-
                                      Código de resultado del proveedor, sin
                                      interpretar
                                  resultGas:
                                    type: string
                                    description: >-
                                      Código de resultado del control de gases,
                                      sin interpretar
                                  month:
                                    type: string
                                    description: >-
                                      Mes que le corresponde según el último
                                      dígito de la patente
                                  station:
                                    type: object
                                    description: Planta revisora donde se realizó
                                    properties:
                                      code:
                                        type: string
                                      region:
                                        type: string
                                      commune:
                                        type: string
                                      concession:
                                        type: string
                                      address:
                                        type: string
                              description:
                                type: string
                                description: Descripción adicional del activo (opcional)
                              clientId:
                                type: string
                              state:
                                type: string
                                description: Estado del activo (opcional)
                              customFields:
                                type: object
                                description: >
                                  Valores de los Campos personalizados de la
                                  empresa, una clave por Nombre interno

                                  (`GET /api/asset-custom-fields` lista las
                                  definiciones). Formato por tipo: `text` string

                                  (se guarda recortado, hasta 1.000 caracteres),
                                  `number` número, `date` `YYYY-MM-DD`,

                                  `select` el `value` de una opción activa,
                                  `boolean` `true` o `false`.


                                  **En las respuestas** (`GET` de lista y
                                  detalle) siempre está presente, con solo los
                                  campos

                                  activos: una clave ausente significa «sin
                                  valor»; los valores de un campo archivado no
                                  salen

                                  y vuelven al restaurarlo.


                                  **Al escribir** (`POST`, `PUT`, `PATCH`) se
                                  mezcla por clave: las claves enviadas se
                                  escriben,

                                  `null` o `""` borran el valor y las ausentes
                                  no se tocan. Una clave desconocida, de un
                                  campo

                                  archivado o con un valor que no cumple el tipo
                                  o las reglas responde 400

                                  `ASSET_CUSTOM_FIELD_VALUE_INVALID` nombrando
                                  la clave. En `POST` y `PUT`, después de

                                  mezclar, el activo debe quedar con todos los
                                  campos obligatorios completos (400 listando

                                  los que faltan); el `PATCH` solo falla si
                                  vacía un obligatorio. El 400 trae en `details`
                                  la

                                  clave (`key`) y, si aplica, la regla que no se
                                  cumple (`rule`), o los obligatorios que faltan

                                  (`missingFields`).
                                additionalProperties:
                                  nullable: true
                                  oneOf:
                                    - type: string
                                    - type: number
                                    - type: boolean
                                example:
                                  codigo_de_inventario: ASM-001
                                  area: taller_mecanico
                                  arrendado: false
                              currentDriver:
                                type: object
                                nullable: true
                                description: >-
                                  Conductor vigente del activo (vínculo
                                  conductor-activo abierto).
                                properties:
                                  id:
                                    type: string
                                  name:
                                    type: string
                                required:
                                  - id
                                  - name
                            required:
                              - name
                              - icon
                              - mainTrackerId
                              - trackers
                              - plate
                              - assetTypeId
              example:
                dryRun: true
                entries:
                  - idField: codigo_de_inventario
                    idValue: ASM-001
                    data:
                      customFields:
                        area: taller_mecanico
                  - idField: plate
                    idValue: RLPD21
                    data:
                      customFields:
                        codigo_de_inventario: ASM-002
      responses:
        '200':
          description: Resultado por fila y resumen
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    example: success
                  data:
                    type: object
                    properties:
                      dryRun:
                        type: boolean
                      summary:
                        type: object
                        properties:
                          total:
                            type: integer
                            example: 2
                          updated:
                            type: integer
                            example: 1
                          failed:
                            type: integer
                            example: 1
                      results:
                        type: array
                        items:
                          type: object
                          required:
                            - index
                            - status
                          properties:
                            index:
                              type: integer
                              description: Posición de la entrada en `entries` (desde 0)
                            status:
                              type: string
                              enum:
                                - updated
                                - notFound
                                - ambiguous
                                - invalid
                                - conflict
                            asset:
                              type: object
                              description: Activo resuelto, si se llegó a resolver
                              properties:
                                id:
                                  type: string
                                name:
                                  type: string
                                  nullable: true
                                plate:
                                  type: string
                                  nullable: true
                            error:
                              type: object
                              description: >-
                                Motivo de la fila que falló, con el mismo `code`
                                y `details` que el `PATCH`
                              properties:
                                code:
                                  type: string
                                  example: ASSET_CUSTOM_FIELD_VALUE_CONFLICT
                                message:
                                  type: string
                                  example: >-
                                    Ya lo tiene el activo Camioneta 01 (QAAA11).
                                    El campo «Código de inventario» no admite
                                    valores repetidos.
                                details:
                                  type: object
                                  additionalProperties: true
                    example:
                      dryRun: true
                      summary:
                        total: 2
                        updated: 1
                        failed: 1
                      results:
                        - index: 0
                          status: updated
                          asset:
                            id: 6650f1a2c9d84e0012345678
                            name: Camioneta 01
                            plate: QAAA11
                        - index: 1
                          status: notFound
                          error:
                            code: ASSET_NOT_FOUND
                            message: Activo no encontrado
        '400':
          description: Error de validación
          content:
            application/json:
              schema:
                oneOf:
                  - type: object
                    properties:
                      error:
                        type: string
                        example: El email es requerido
                  - type: object
                    properties:
                      status:
                        type: string
                        example: failed
                      message:
                        type: string
                        example: Error de validación
                      errors:
                        type: array
                        items:
                          type: object
                          properties:
                            path:
                              type: string
                            message:
                              type: string
        '401':
          description: No autorizado
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: Token inválido o expirado
        '403':
          description: Sin permisos
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: No tiene permisos para realizar esta acción
        '500':
          description: Error interno del servidor
          content:
            application/json:
              schema:
                oneOf:
                  - type: object
                    properties:
                      message:
                        type: string
                        example: Error interno del servidor
                  - type: object
                    properties:
                      status:
                        type: string
                        example: failed
                      message:
                        type: string
                        example: Error interno del servidor
      security:
        - bearerAuth: []
components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: >-
        Token de sesión Better Auth o API token (`atk_...`) en el header
        `Authorization: Bearer <token>`. Los JWT legacy ya no son válidos.
    cookieAuth:
      type: apiKey
      in: cookie
      name: better-auth.session_token
      description: >-
        Cookie de sesión Better Auth emitida al iniciar sesión en el frontend
        web. En producción el nombre lleva prefijo `__Secure-`.

````

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