> ## 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.

# Enviar una inspección

> `multipart/form-data` con el campo de texto `payload` (JSON, ver `CreateInspectionPayload`) y un archivo
por adjunto, cuyo nombre de parte es el `fieldId` del campo. El formulario debe estar activo y asignado
al activo. El resultado se calcula en el servidor: si alguna respuesta es crítica la inspección queda
`unfit`, se crea un defecto por respuesta crítica, el activo pasa a fuera de servicio en Mantención y se
avisa por correo a los usuarios con `access_maintenance`.

Idempotente por `clientSubmissionId`: un reenvío devuelve la inspección ya guardada.

**Permisos requeridos:** `access_inspections`




## OpenAPI

````yaml /openapi.json post /api/inspections
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 - Vehículos
    description: Operaciones relacionadas con tipos de vehículos
  - 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 - 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, grupos o
      todos los 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: Mantenimiento - Importación de Facturas
    description: Importación de facturas con extracción por IA
  - 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: Soporte
    description: Portal del cliente — tickets de soporte de la empresa (proyección de Raúl)
paths:
  /api/inspections:
    post:
      tags:
        - Inspecciones
      summary: Enviar una inspección
      description: >
        `multipart/form-data` con el campo de texto `payload` (JSON, ver
        `CreateInspectionPayload`) y un archivo

        por adjunto, cuyo nombre de parte es el `fieldId` del campo. El
        formulario debe estar activo y asignado

        al activo. El resultado se calcula en el servidor: si alguna respuesta
        es crítica la inspección queda

        `unfit`, se crea un defecto por respuesta crítica, el activo pasa a
        fuera de servicio en Mantención y se

        avisa por correo a los usuarios con `access_maintenance`.


        Idempotente por `clientSubmissionId`: un reenvío devuelve la inspección
        ya guardada.


        **Permisos requeridos:** `access_inspections`
      requestBody:
        required: true
        content:
          multipart/form-data:
            schema:
              type: object
              required:
                - payload
              properties:
                payload:
                  type: string
                  description: JSON serializado de `CreateInspectionPayload`.
              additionalProperties:
                type: string
                format: binary
      responses:
        '201':
          description: Inspección creada
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    example: success
                  data:
                    type: object
                    properties:
                      _id:
                        type: string
                      clientId:
                        type: string
                      assetId:
                        type: string
                      submittedBy:
                        type: string
                      clientSubmissionId:
                        type: string
                        format: uuid
                      result:
                        type: string
                        enum:
                          - fit
                          - unfit
                        description: >-
                          «No apta» (`unfit`) cuando alguna respuesta elegida es
                          una opción crítica.
                      dynamicFormId:
                        type: string
                      formVersion:
                        type: integer
                      formSnapshot:
                        type: object
                        description: Copia congelada del formulario tal como se llenó.
                        properties:
                          name:
                            type: string
                          fields:
                            type: array
                            items:
                              type: object
                              description: >
                                Campo del formulario. `type` fija qué parámetros
                                aplican:

                                text/textarea (`minLength`, `maxLength`), number
                                (`min`, `max`), radio_group/dropdown
                                (`options`),

                                checkbox_group (`options`, `minChecked`,
                                `maxChecked`), toggle (`criticalWhen`), rating
                                (`maxStars`),

                                date (`disableFuture`, `disablePast`),
                                photo/signature (`maxFiles`), file (`maxFiles`,
                                `allowedExtensions`),

                                separator (sin respuesta).
                              required:
                                - fieldId
                                - type
                                - label
                                - required
                              properties:
                                fieldId:
                                  type: string
                                  description: >-
                                    Estable entre versiones; un fieldId
                                    existente nunca cambia de `type`.
                                type:
                                  type: string
                                  enum:
                                    - text
                                    - textarea
                                    - number
                                    - radio_group
                                    - checkbox_group
                                    - dropdown
                                    - toggle
                                    - rating
                                    - date
                                    - photo
                                    - signature
                                    - file
                                    - separator
                                label:
                                  type: string
                                  example: Estado de frenos
                                required:
                                  type: boolean
                                helperText:
                                  type: string
                                minLength:
                                  type: integer
                                maxLength:
                                  type: integer
                                min:
                                  type: number
                                max:
                                  type: number
                                options:
                                  type: array
                                  items:
                                    type: object
                                    description: >-
                                      Opción de un campo radio_group,
                                      checkbox_group o dropdown. `optionId` es
                                      estable entre versiones.
                                    required:
                                      - optionId
                                      - label
                                    properties:
                                      optionId:
                                        type: string
                                        example: 3f1c2a8e-4b8d-4c1a-9a6e-7d2f0b1c9e55
                                      label:
                                        type: string
                                        example: Dañado
                                      critical:
                                        type: boolean
                                        description: >-
                                          Elegir esta opción vuelve «no apta» la
                                          inspección.
                                        example: true
                                minChecked:
                                  type: integer
                                maxChecked:
                                  type: integer
                                criticalWhen:
                                  type: boolean
                                  description: Valor del toggle que se considera crítico.
                                maxStars:
                                  type: integer
                                disableFuture:
                                  type: boolean
                                disablePast:
                                  type: boolean
                                maxFiles:
                                  type: integer
                                allowedExtensions:
                                  type: array
                                  items:
                                    type: string
                                  example:
                                    - pdf
                      values:
                        type: object
                        additionalProperties: true
                      attachments:
                        type: array
                        items:
                          type: object
                          properties:
                            fieldId:
                              type: string
                            url:
                              type: string
                              description: >-
                                En el detalle llega firmada (SAS de lectura,
                                vence).
                            name:
                              type: string
                            mimeType:
                              type: string
                            size:
                              type: integer
                      capturedAt:
                        type: string
                        format: date-time
                      receivedAt:
                        type: string
                        format: date-time
                      location:
                        type: object
                        description: >-
                          Ubicación del teléfono contrastada con la última
                          posición del tracker del activo.
                        properties:
                          phone:
                            type: object
                            required:
                              - lat
                              - lng
                            properties:
                              lat:
                                type: number
                                example: -33.45
                              lng:
                                type: number
                                example: -70.66
                              accuracy:
                                type: number
                                description: Precisión del GPS del teléfono en metros.
                              mocked:
                                type: boolean
                                description: El teléfono informó ubicación simulada.
                                default: false
                          tracker:
                            type: object
                            properties:
                              lat:
                                type: number
                              lng:
                                type: number
                              timestamp:
                                type: string
                                format: date-time
                          distanceMeters:
                            type: number
                          suspicious:
                            type: boolean
                          suspiciousReasons:
                            type: array
                            items:
                              type: string
                              enum:
                                - out_of_radius
                                - mocked_location
                                - stale_tracker
                                - no_tracker_position
                                - clock_skew
                      createdAt:
                        type: string
                        format: date-time
                      updatedAt:
                        type: string
                        format: date-time
        '400':
          description: >-
            Payload, archivos o respuestas inválidos
            (`INSPECTION_VALUES_INVALID`, `DYNAMIC_FORM_VALUES_INVALID`,
            `INSPECTION_UNSUPPORTED_MIME_TYPE`)
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    example: failed
                  code:
                    type: string
                    example: DYNAMIC_FORM_VALUES_INVALID
                  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
        '404':
          description: >-
            Activo fuera de alcance o formulario no asignado/inactivo
            (`INSPECTION_ASSET_NOT_FOUND`, `DYNAMIC_FORM_NOT_FOUND`)
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    example: failed
                  code:
                    type: string
                    example: DYNAMIC_FORM_NOT_FOUND
                  message:
                    type: string
        '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
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-`.

````