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

# Reconocimiento de matrículas y vehículos

> Consulte eventos de detección de matrículas, busque placas con coincidencia aproximada, cree una lista de vigilancia de vehículos guardados, genere informes por dispositivo y exporte datos de vehículos como CSV con la API de Rhombus.

<Note>
  Esta página fue traducida automáticamente. Si encuentra errores o tiene sugerencias, [contáctenos](mailto:support@rhombus.com).
</Note>

## Descripción general

Las cámaras Rhombus con reconocimiento de matrículas (LPR) detectan vehículos y leen sus matrículas a medida que pasan por una escena. Cada detección se convierte en un evento de vehículo que registra la placa, la cámara y la ubicación que la reportan, una imagen capturada y la hora en que fue vista.

A través de la API, puede:

* **Consultar eventos de detección** en toda su organización, filtrados por dispositivo, ubicación, placa, nombre o etiqueta
* **Buscar una placa específica** con coincidencia exacta o aproximada para encontrar cada vez que fue vista
* **Crear una lista de vigilancia** de vehículos guardados ("placas de interés") con indicadores de alerta y confianza, nombres y etiquetas
* **Generar informes por dispositivo** que agrupan las detecciones por hora, día, semana o mes
* **Exportar eventos de vehículos** como CSV para análisis externo o registro

<Note>
  Cada marca de tiempo de evento de vehículo se reporta en **milisegundos de época (epoch)**, pero el nombre del campo difiere según el endpoint (`startTimeMs`, `startTime`, `timestampMs`, `createdAtMillis`, `eventTimestamp`). Cada sección a continuación indica el campo exacto que debe usar. No existe un campo de región, estado ni una puntuación de confianza numérica en los eventos de vehículos; no espere ninguno.
</Note>

## Requisitos previos

<Note>
  Antes de comenzar, asegúrese de tener:

  * Una **clave de API de Rhombus** con acceso de lectura a cámaras (generada en la Consola de Rhombus en Configuración > API). Reportar una lectura incorrecta requiere además el permiso **`MANAGE_LICENSEPLATES`**, y la exportación CSV requiere el permiso **`REPORT_ADMINISTRATION`**.
  * Al menos una **cámara compatible con LPR** desplegada y leyendo placas en una ubicación
  * El **UUID del dispositivo** de esa cámara, que puede obtener de los endpoints de cámara o de la Consola de Rhombus
</Note>

Todas las solicitudes son `POST` a `https://api2.rhombussystems.com` y se autentican con los encabezados `x-auth-scheme` y `x-auth-apikey` que se muestran en cada ejemplo.

## Flujo 1: Consultar detecciones recientes

Use `getVehicleEvents` para recuperar eventos de detección en toda su organización. Este es el endpoint principal para llevar la actividad de LPR a un panel o informe.

La solicitud combina dos tipos de criterios que se comportan de manera diferente:

* Los **campos de filtro** (`deviceUuidFilter`, `locationUuidFilter`) se combinan con **Y (AND)**: un evento devuelto debe satisfacer *todos* los filtros que proporcione.
* Los **campos de consulta** (`nameQuery`, `licensePlateExactQuery`, `vehicleLabelQuery`, `licensePlateFuzzyQuery`, `unnamedQuery`) se combinan con **O (OR)**: un evento devuelto debe satisfacer *al menos una* de las consultas que proporcione.

<CodeGroup>
  ```python Python theme={null}
  import requests
  import time

  headers = {
      "x-auth-scheme": "api-token",
      "x-auth-apikey": "YOUR_API_KEY",
      "Content-Type": "application/json"
  }

  # Consultar las detecciones de las últimas 24 horas de una cámara
  now_ms = int(time.time() * 1000)
  one_day_ago_ms = now_ms - (24 * 60 * 60 * 1000)

  response = requests.post(
      "https://api2.rhombussystems.com/api/vehicle/getVehicleEvents",
      headers=headers,
      json={
          "startTimeMs": one_day_ago_ms,
          "endTimeMs": now_ms,
          "deviceUuidFilter": ["YOUR_CAMERA_UUID"]
      }
  )

  data = response.json()
  for event in data.get("events", []):
      plate = event.get("vehicleLicensePlate")
      ts = event.get("eventTimestamp")
      device = event.get("deviceUuid")
      print(f"[{ts}] {plate} vista por {device}")
  ```

  ```javascript JavaScript theme={null}
  const now = Date.now();
  const oneDayAgo = now - (24 * 60 * 60 * 1000);

  const response = await fetch('https://api2.rhombussystems.com/api/vehicle/getVehicleEvents', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'x-auth-scheme': 'api-token',
      'x-auth-apikey': 'YOUR_API_KEY'
    },
    body: JSON.stringify({
      startTimeMs: oneDayAgo,
      endTimeMs: now,
      deviceUuidFilter: ['YOUR_CAMERA_UUID']
    })
  });

  const data = await response.json();
  for (const event of data.events || []) {
    console.log(`[${new Date(event.eventTimestamp).toISOString()}] ${event.vehicleLicensePlate} vista por ${event.deviceUuid}`);
  }
  ```

  ```bash cURL theme={null}
  curl -X POST https://api2.rhombussystems.com/api/vehicle/getVehicleEvents \
    -H "Content-Type: application/json" \
    -H "x-auth-scheme: api-token" \
    -H "x-auth-apikey: YOUR_API_KEY" \
    -d '{
      "startTimeMs": 1712620800000,
      "endTimeMs": 1712707200000,
      "deviceUuidFilter": ["YOUR_CAMERA_UUID"]
    }'
  ```
</CodeGroup>

### Campos de solicitud

<ParamField body="startTimeMs" type="integer">
  Inicio de la ventana de tiempo (más antiguo) en milisegundos de época.
</ParamField>

<ParamField body="endTimeMs" type="integer">
  Fin de la ventana de tiempo (más reciente) en milisegundos de época.
</ParamField>

<ParamField body="deviceUuidFilter" type="string[]">
  Devuelve solo eventos de estos UUID de cámara. Se combina con Y (AND) con otros filtros.
</ParamField>

<ParamField body="locationUuidFilter" type="string[]">
  Devuelve solo eventos de estos UUID de ubicación. Se combina con Y (AND) con otros filtros.
</ParamField>

<ParamField body="nameQuery" type="string[]">
  Devuelve eventos cuyo nombre de vehículo coincida con uno de estos valores. Se combina con O (OR) con otras consultas.
</ParamField>

<ParamField body="licensePlateExactQuery" type="string[]">
  Devuelve eventos cuya placa coincida exactamente con uno de estos valores. Se combina con O (OR) con otras consultas.
</ParamField>

<ParamField body="vehicleLabelQuery" type="string[]">
  Devuelve eventos etiquetados con una de estas etiquetas de vehículo. Se combina con O (OR) con otras consultas.
</ParamField>

<ParamField body="licensePlateFuzzyQuery" type="string">
  Devuelve eventos cuya placa coincida aproximadamente con esta placa parcial o completa, tolerando lecturas incorrectas de caracteres. Se combina con O (OR) con otras consultas.
</ParamField>

<ParamField body="unnamedQuery" type="boolean">
  Si es `false`, devuelve solo eventos que tienen un nombre; si es `true`, devuelve solo eventos sin nombre. Omítalo si no lo necesita. Se combina con O (OR) con otras consultas.
</ParamField>

### Campos de respuesta

La respuesta contiene un arreglo `events`. Cada evento tiene estos campos:

<ResponseField name="uuid" type="string">
  Identificador único del evento de vehículo.
</ResponseField>

<ResponseField name="orgUuid" type="string">
  Organización a la que pertenece el evento.
</ResponseField>

<ResponseField name="deviceUuid" type="string">
  UUID de la cámara que reportó la detección.
</ResponseField>

<ResponseField name="locationUuid" type="string">
  Ubicación donde ocurrió la detección.
</ResponseField>

<ResponseField name="vehicleLicensePlate" type="string">
  La cadena de matrícula reconocida.
</ResponseField>

<ResponseField name="matchingLicensePlates" type="string[]">
  Cadenas de placa consideradas coincidencias completas para esta detección.
</ResponseField>

<ResponseField name="partialLicensePlates" type="string[]">
  Cadenas de placa consideradas coincidencias parciales para esta detección.
</ResponseField>

<ResponseField name="imageS3Key" type="string">
  Clave S3 de la imagen completa de la detección. Es una clave de almacenamiento, no una URL.
</ResponseField>

<ResponseField name="thumbnailS3Key" type="string">
  Clave S3 de la miniatura de la detección. Es una clave de almacenamiento, no una URL.
</ResponseField>

<ResponseField name="eventTimestamp" type="integer">
  Cuándo ocurrió la detección, en milisegundos de época.
</ResponseField>

<ResponseField name="name" type="string">
  Nombre del vehículo, si la placa está asociada a un vehículo guardado.
</ResponseField>

<Warning>
  `imageS3Key` y `thumbnailS3Key` son claves de almacenamiento S3, no URL de imágenes visualizables directamente. Use los endpoints de medios y grabaciones para recuperar los bytes de la imagen.
</Warning>

<Note>
  Los endpoints `getRecentVehicleEvents`, `getRecentVehicleEventsByLocation` y `getRecentVehicleEventsForVehicle` son heredados (legacy). Prefiera `getVehicleEvents` para nuevas integraciones: su modelo de filtros/consultas los reemplaza.
</Note>

## Flujo 2: Buscar una placa con coincidencia aproximada

Cuando tenga una placa específica que rastrear, `searchLicensePlates` encuentra cada evento que coincide con ella. Habilite `fuzzy` para tolerar lecturas incorrectas de caracteres, útil cuando una placa está parcialmente obstruida o la lectura original fue imperfecta.

<CodeGroup>
  ```python Python theme={null}
  import requests
  import time

  headers = {
      "x-auth-scheme": "api-token",
      "x-auth-apikey": "YOUR_API_KEY",
      "Content-Type": "application/json"
  }

  now_ms = int(time.time() * 1000)
  one_week_ago_ms = now_ms - (7 * 24 * 60 * 60 * 1000)

  response = requests.post(
      "https://api2.rhombussystems.com/api/search/searchLicensePlates",
      headers=headers,
      json={
          "licensePlate": "ABC123",
          "startTime": one_week_ago_ms,
          "endTime": now_ms,
          "fuzzy": True
      }
  )

  data = response.json()
  for hit in data.get("vehicleEvents", []):
      plate = hit.get("vehicleLicensePlate")
      matched = hit.get("searchMatchedTerm")
      match_type = hit.get("searchMatchedType")
      print(f"{plate} coincidió con '{matched}' ({match_type}) a las {hit.get('eventTimestamp')}")
  ```

  ```javascript JavaScript theme={null}
  const now = Date.now();
  const oneWeekAgo = now - (7 * 24 * 60 * 60 * 1000);

  const response = await fetch('https://api2.rhombussystems.com/api/search/searchLicensePlates', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'x-auth-scheme': 'api-token',
      'x-auth-apikey': 'YOUR_API_KEY'
    },
    body: JSON.stringify({
      licensePlate: 'ABC123',
      startTime: oneWeekAgo,
      endTime: now,
      fuzzy: true
    })
  });

  const data = await response.json();
  for (const hit of data.vehicleEvents || []) {
    console.log(`${hit.vehicleLicensePlate} coincidió con '${hit.searchMatchedTerm}' (${hit.searchMatchedType})`);
  }
  ```

  ```bash cURL theme={null}
  curl -X POST https://api2.rhombussystems.com/api/search/searchLicensePlates \
    -H "Content-Type: application/json" \
    -H "x-auth-scheme: api-token" \
    -H "x-auth-apikey: YOUR_API_KEY" \
    -d '{
      "licensePlate": "ABC123",
      "startTime": 1712102400000,
      "endTime": 1712707200000,
      "fuzzy": true
    }'
  ```
</CodeGroup>

### Campos de solicitud

<ParamField body="licensePlate" type="string" required>
  El número de placa que se busca.
</ParamField>

<ParamField body="startTime" type="integer">
  Inicio de la ventana de búsqueda en milisegundos de época. Tenga en cuenta que el campo se llama `startTime`, no `startTimeMs`.
</ParamField>

<ParamField body="endTime" type="integer">
  Fin de la ventana de búsqueda en milisegundos de época.
</ParamField>

<ParamField body="deviceUuids" type="string[]">
  Limita la búsqueda a estos UUID de cámara.
</ParamField>

<ParamField body="fuzzy" type="boolean">
  Cuando es `true`, permite la coincidencia aproximada para caracteres leídos incorrectamente.
</ParamField>

<Warning>
  El campo `forcedFuzziness` está obsoleto. Use el indicador booleano `fuzzy` en su lugar.
</Warning>

### Campos de respuesta

El arreglo `vehicleEvents` contiene todos los [campos de evento de vehículo](#campos-de-respuesta) del Flujo 1, más dos campos específicos de la búsqueda:

<ResponseField name="searchMatchedTerm" type="string">
  El término de placa que coincidió con su consulta.
</ResponseField>

<ResponseField name="searchMatchedType" type="string">
  Cómo se realizó la coincidencia (por ejemplo, exacta frente a aproximada).
</ResponseField>

## Flujo 3: Crear una lista de vigilancia de vehículos guardados

Un vehículo guardado es una "placa de interés" que desea rastrear. Cada vehículo guardado lleva un indicador `alert` (notificar cuando se ve) y un indicador `trust` (tratar como conocido/seguro), además de un nombre, una descripción y etiquetas opcionales. Guardar un vehículo también permite que Rhombus adjunte el `name` a los futuros eventos de detección de esa placa.

### Guardar un vehículo

<CodeGroup>
  ```python Python theme={null}
  import requests
  import time

  headers = {
      "x-auth-scheme": "api-token",
      "x-auth-apikey": "YOUR_API_KEY",
      "Content-Type": "application/json"
  }

  response = requests.post(
      "https://api2.rhombussystems.com/api/vehicle/saveVehicle",
      headers=headers,
      json={
          "vehicleLicensePlate": "ABC123",
          "createdAtMillis": int(time.time() * 1000),
          "name": "Furgoneta de reparto",
          "description": "Ford Transit blanca - proveedor aprobado",
          "alert": True,
          "trust": True
      }
  )

  print(response.json())
  ```

  ```javascript JavaScript theme={null}
  const response = await fetch('https://api2.rhombussystems.com/api/vehicle/saveVehicle', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'x-auth-scheme': 'api-token',
      'x-auth-apikey': 'YOUR_API_KEY'
    },
    body: JSON.stringify({
      vehicleLicensePlate: 'ABC123',
      createdAtMillis: Date.now(),
      name: 'Furgoneta de reparto',
      description: 'Ford Transit blanca - proveedor aprobado',
      alert: true,
      trust: true
    })
  });

  console.log(await response.json());
  ```

  ```bash cURL theme={null}
  curl -X POST https://api2.rhombussystems.com/api/vehicle/saveVehicle \
    -H "Content-Type: application/json" \
    -H "x-auth-scheme: api-token" \
    -H "x-auth-apikey: YOUR_API_KEY" \
    -d '{
      "vehicleLicensePlate": "ABC123",
      "createdAtMillis": 1712707200000,
      "name": "Furgoneta de reparto",
      "description": "Ford Transit blanca - proveedor aprobado",
      "alert": true,
      "trust": true
    }'
  ```
</CodeGroup>

<ParamField body="vehicleLicensePlate" type="string" required>
  La placa que identifica a este vehículo guardado.
</ParamField>

<ParamField body="createdAtMillis" type="integer">
  Marca de tiempo de creación en milisegundos de época.
</ParamField>

<ParamField body="alert" type="boolean">
  Si se debe generar una alerta cuando se detecta este vehículo.
</ParamField>

<ParamField body="trust" type="boolean">
  Si este vehículo es de confianza (conocido/seguro).
</ParamField>

<ParamField body="name" type="string">
  Nombre para mostrar del vehículo.
</ParamField>

<ParamField body="description" type="string">
  Descripción de texto libre.
</ParamField>

<ParamField body="thumbnailS3Key" type="string">
  Clave S3 de una imagen en miniatura del vehículo.
</ParamField>

### Listar vehículos guardados

Recupere todos los vehículos guardados de su organización. El cuerpo de la solicitud está vacío.

<CodeGroup>
  ```python Python theme={null}
  import requests

  headers = {
      "x-auth-scheme": "api-token",
      "x-auth-apikey": "YOUR_API_KEY",
      "Content-Type": "application/json"
  }

  response = requests.post(
      "https://api2.rhombussystems.com/api/vehicle/getVehicles",
      headers=headers,
      json={}
  )

  data = response.json()
  for vehicle in data.get("vehicles", []):
      print(f"{vehicle.get('licensePlate')}: {vehicle.get('name')} "
            f"(alert={vehicle.get('alert')}, trust={vehicle.get('trust')})")
  ```

  ```javascript JavaScript theme={null}
  const response = await fetch('https://api2.rhombussystems.com/api/vehicle/getVehicles', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'x-auth-scheme': 'api-token',
      'x-auth-apikey': 'YOUR_API_KEY'
    },
    body: JSON.stringify({})
  });

  const data = await response.json();
  for (const vehicle of data.vehicles || []) {
    console.log(`${vehicle.licensePlate}: ${vehicle.name} (alert=${vehicle.alert}, trust=${vehicle.trust})`);
  }
  ```

  ```bash cURL theme={null}
  curl -X POST https://api2.rhombussystems.com/api/vehicle/getVehicles \
    -H "Content-Type: application/json" \
    -H "x-auth-scheme: api-token" \
    -H "x-auth-apikey: YOUR_API_KEY" \
    -d '{}'
  ```
</CodeGroup>

Cada entrada del arreglo `vehicles` es un vehículo guardado:

<ResponseField name="licensePlate" type="string">
  La placa que identifica al vehículo guardado.
</ResponseField>

<ResponseField name="orgUuid" type="string">
  Organización a la que pertenece el vehículo.
</ResponseField>

<ResponseField name="createdAtMillis" type="integer">
  Cuándo se guardó el vehículo, en milisegundos de época.
</ResponseField>

<ResponseField name="alert" type="boolean">
  Si las detecciones generan una alerta.
</ResponseField>

<ResponseField name="trust" type="boolean">
  Si el vehículo es de confianza.
</ResponseField>

<ResponseField name="name" type="string">
  Nombre para mostrar.
</ResponseField>

<ResponseField name="description" type="string">
  Descripción de texto libre.
</ResponseField>

<ResponseField name="thumbnailS3Key" type="string">
  Clave S3 de la miniatura del vehículo.
</ResponseField>

### Agregar y quitar etiquetas

Las etiquetas agrupan los vehículos guardados en categorías como "empleado", "proveedor" o "marcado". Agregue una etiqueta a una placa con `addVehicleLabel` y quítela con `removeVehicleLabel`.

<CodeGroup>
  ```python Python theme={null}
  import requests

  headers = {
      "x-auth-scheme": "api-token",
      "x-auth-apikey": "YOUR_API_KEY",
      "Content-Type": "application/json"
  }

  response = requests.post(
      "https://api2.rhombussystems.com/api/vehicle/addVehicleLabel",
      headers=headers,
      json={
          "vehicleLicensePlate": "ABC123",
          "label": "Proveedor aprobado"
      }
  )

  print(response.json())
  ```

  ```javascript JavaScript theme={null}
  const response = await fetch('https://api2.rhombussystems.com/api/vehicle/addVehicleLabel', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'x-auth-scheme': 'api-token',
      'x-auth-apikey': 'YOUR_API_KEY'
    },
    body: JSON.stringify({
      vehicleLicensePlate: 'ABC123',
      label: 'Proveedor aprobado'
    })
  });

  console.log(await response.json());
  ```

  ```bash cURL theme={null}
  curl -X POST https://api2.rhombussystems.com/api/vehicle/addVehicleLabel \
    -H "Content-Type: application/json" \
    -H "x-auth-scheme: api-token" \
    -H "x-auth-apikey: YOUR_API_KEY" \
    -d '{
      "vehicleLicensePlate": "ABC123",
      "label": "Proveedor aprobado"
    }'
  ```
</CodeGroup>

Para ver todas las etiquetas asignadas en su organización, llame a `getVehicleLabelsForOrg`. Su respuesta contiene un mapa `vehicleLabels` indexado por matrícula, donde cada valor es el conjunto de etiquetas de esa placa.

<CodeGroup>
  ```python Python theme={null}
  import requests

  headers = {
      "x-auth-scheme": "api-token",
      "x-auth-apikey": "YOUR_API_KEY",
      "Content-Type": "application/json"
  }

  response = requests.post(
      "https://api2.rhombussystems.com/api/vehicle/getVehicleLabelsForOrg",
      headers=headers,
      json={}
  )

  labels = response.json().get("vehicleLabels", {})
  for plate, plate_labels in labels.items():
      print(f"{plate}: {', '.join(plate_labels)}")
  ```

  ```javascript JavaScript theme={null}
  const response = await fetch('https://api2.rhombussystems.com/api/vehicle/getVehicleLabelsForOrg', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'x-auth-scheme': 'api-token',
      'x-auth-apikey': 'YOUR_API_KEY'
    },
    body: JSON.stringify({})
  });

  const data = await response.json();
  for (const [plate, plateLabels] of Object.entries(data.vehicleLabels || {})) {
    console.log(`${plate}: ${plateLabels.join(', ')}`);
  }
  ```

  ```bash cURL theme={null}
  curl -X POST https://api2.rhombussystems.com/api/vehicle/getVehicleLabelsForOrg \
    -H "Content-Type: application/json" \
    -H "x-auth-scheme: api-token" \
    -H "x-auth-apikey: YOUR_API_KEY" \
    -d '{}'
  ```
</CodeGroup>

### Asociar eventos anteriores con un vehículo guardado

Si una placa fue detectada antes de que la guardara como vehículo, use `associateEventsToVehicle` para adjuntar esos eventos de detección históricos al vehículo guardado. Pase los UUID de los eventos (del Flujo 1 o 2) y la placa.

<CodeGroup>
  ```python Python theme={null}
  import requests

  headers = {
      "x-auth-scheme": "api-token",
      "x-auth-apikey": "YOUR_API_KEY",
      "Content-Type": "application/json"
  }

  response = requests.post(
      "https://api2.rhombussystems.com/api/vehicle/associateEventsToVehicle",
      headers=headers,
      json={
          "vehicleLicensePlate": "ABC123",
          "eventUuids": ["EVENT_UUID_1", "EVENT_UUID_2"]
      }
  )

  print(response.json())
  ```

  ```javascript JavaScript theme={null}
  const response = await fetch('https://api2.rhombussystems.com/api/vehicle/associateEventsToVehicle', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'x-auth-scheme': 'api-token',
      'x-auth-apikey': 'YOUR_API_KEY'
    },
    body: JSON.stringify({
      vehicleLicensePlate: 'ABC123',
      eventUuids: ['EVENT_UUID_1', 'EVENT_UUID_2']
    })
  });

  console.log(await response.json());
  ```

  ```bash cURL theme={null}
  curl -X POST https://api2.rhombussystems.com/api/vehicle/associateEventsToVehicle \
    -H "Content-Type: application/json" \
    -H "x-auth-scheme: api-token" \
    -H "x-auth-apikey: YOUR_API_KEY" \
    -d '{
      "vehicleLicensePlate": "ABC123",
      "eventUuids": ["EVENT_UUID_1", "EVENT_UUID_2"]
    }'
  ```
</CodeGroup>

### Eliminar un vehículo guardado

Quite un vehículo de su lista de vigilancia por su placa.

<CodeGroup>
  ```python Python theme={null}
  import requests

  headers = {
      "x-auth-scheme": "api-token",
      "x-auth-apikey": "YOUR_API_KEY",
      "Content-Type": "application/json"
  }

  response = requests.post(
      "https://api2.rhombussystems.com/api/vehicle/deleteVehicle",
      headers=headers,
      json={
          "vehicleLicensePlate": "ABC123"
      }
  )

  print(response.json())
  ```

  ```javascript JavaScript theme={null}
  const response = await fetch('https://api2.rhombussystems.com/api/vehicle/deleteVehicle', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'x-auth-scheme': 'api-token',
      'x-auth-apikey': 'YOUR_API_KEY'
    },
    body: JSON.stringify({
      vehicleLicensePlate: 'ABC123'
    })
  });

  console.log(await response.json());
  ```

  ```bash cURL theme={null}
  curl -X POST https://api2.rhombussystems.com/api/vehicle/deleteVehicle \
    -H "Content-Type: application/json" \
    -H "x-auth-scheme: api-token" \
    -H "x-auth-apikey: YOUR_API_KEY" \
    -d '{"vehicleLicensePlate": "ABC123"}'
  ```
</CodeGroup>

<Tip>
  Cuando una detección se lee mal o se atribuye a la placa equivocada, repórtela con `reportVehicleEvent` (pasando el `eventUuid` del evento). Esta retroalimentación ayuda a mejorar la precisión del reconocimiento. Reportar requiere el permiso `MANAGE_LICENSEPLATES` en su clave de API.
</Tip>

## Flujo 4: Informes por dispositivo y exportación CSV

### Informe por dispositivo

`getLicensePlatesByDevice` devuelve las detecciones de matrículas de una sola cámara, agrupadas por un intervalo de informe. Proporcione la hora de referencia como `timestampMs` (milisegundos de época) y elija un `interval`.

<CodeGroup>
  ```python Python theme={null}
  import requests
  import time

  headers = {
      "x-auth-scheme": "api-token",
      "x-auth-apikey": "YOUR_API_KEY",
      "Content-Type": "application/json"
  }

  response = requests.post(
      "https://api2.rhombussystems.com/api/report/getLicensePlatesByDevice",
      headers=headers,
      json={
          "deviceUuid": "YOUR_CAMERA_UUID",
          "timestampMs": int(time.time() * 1000),
          "interval": "DAILY"
      }
  )

  data = response.json()
  for event in data.get("licensePlateEvents", []):
      print(f"{event.get('vehicleLicensePlate')} a las {event.get('eventTimestamp')}")
  ```

  ```javascript JavaScript theme={null}
  const response = await fetch('https://api2.rhombussystems.com/api/report/getLicensePlatesByDevice', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'x-auth-scheme': 'api-token',
      'x-auth-apikey': 'YOUR_API_KEY'
    },
    body: JSON.stringify({
      deviceUuid: 'YOUR_CAMERA_UUID',
      timestampMs: Date.now(),
      interval: 'DAILY'
    })
  });

  const data = await response.json();
  for (const event of data.licensePlateEvents || []) {
    console.log(`${event.vehicleLicensePlate} a las ${event.eventTimestamp}`);
  }
  ```

  ```bash cURL theme={null}
  curl -X POST https://api2.rhombussystems.com/api/report/getLicensePlatesByDevice \
    -H "Content-Type: application/json" \
    -H "x-auth-scheme: api-token" \
    -H "x-auth-apikey: YOUR_API_KEY" \
    -d '{
      "deviceUuid": "YOUR_CAMERA_UUID",
      "timestampMs": 1712707200000,
      "interval": "DAILY"
    }'
  ```
</CodeGroup>

<ParamField body="deviceUuid" type="string" required>
  El UUID de cámara sobre el que se genera el informe.
</ParamField>

<ParamField body="timestampMs" type="integer">
  Hora de referencia para el informe, como marca de tiempo UNIX en milisegundos.
</ParamField>

<ParamField body="interval" type="string" required>
  Agrupación del informe. Uno de `HOURLY`, `DAILY`, `WEEKLY` o `MONTHLY`.
</ParamField>

<Warning>
  El campo `dateLocal` está obsoleto. Use `timestampMs` en su lugar.
</Warning>

El arreglo `licensePlateEvents` de la respuesta usa los mismos [campos de evento de vehículo](#campos-de-respuesta) descritos en el Flujo 1.

### Exportar a CSV

`export/vehicleEventsV2` transmite los eventos de vehículos coincidentes como CSV. Acepta el **mismo cuerpo de solicitud que `getVehicleEvents`** (Flujo 1) —los campos de filtro y consulta, combinados con Y (AND) y O (OR) de la misma manera— y devuelve `text/csv` directamente en el cuerpo de la respuesta en lugar de JSON. Este endpoint requiere el permiso `REPORT_ADMINISTRATION`.

<CodeGroup>
  ```python Python theme={null}
  import requests
  import time

  headers = {
      "x-auth-scheme": "api-token",
      "x-auth-apikey": "YOUR_API_KEY",
      "Content-Type": "application/json"
  }

  now_ms = int(time.time() * 1000)
  thirty_days_ago_ms = now_ms - (30 * 24 * 60 * 60 * 1000)

  response = requests.post(
      "https://api2.rhombussystems.com/api/export/vehicleEventsV2",
      headers=headers,
      json={
          "startTimeMs": thirty_days_ago_ms,
          "endTimeMs": now_ms,
          "deviceUuidFilter": ["YOUR_CAMERA_UUID"]
      }
  )

  with open("vehicle_events.csv", "w") as f:
      f.write(response.text)
  print("Eventos de vehículos exportados a vehicle_events.csv")
  ```

  ```javascript JavaScript theme={null}
  const now = Date.now();
  const thirtyDaysAgo = now - (30 * 24 * 60 * 60 * 1000);

  const response = await fetch('https://api2.rhombussystems.com/api/export/vehicleEventsV2', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'x-auth-scheme': 'api-token',
      'x-auth-apikey': 'YOUR_API_KEY'
    },
    body: JSON.stringify({
      startTimeMs: thirtyDaysAgo,
      endTimeMs: now,
      deviceUuidFilter: ['YOUR_CAMERA_UUID']
    })
  });

  // La respuesta es texto CSV, no JSON
  const csvData = await response.text();
  console.log(csvData);
  ```

  ```bash cURL theme={null}
  curl -X POST https://api2.rhombussystems.com/api/export/vehicleEventsV2 \
    -H "Content-Type: application/json" \
    -H "x-auth-scheme: api-token" \
    -H "x-auth-apikey: YOUR_API_KEY" \
    -d '{
      "startTimeMs": 1710115200000,
      "endTimeMs": 1712707200000,
      "deviceUuidFilter": ["YOUR_CAMERA_UUID"]
    }' \
    -o vehicle_events.csv
  ```
</CodeGroup>

<Note>
  `export/vehicleEventsV2` reemplaza al endpoint anterior `export/vehicleEvents`, que está obsoleto. Use V2 para nuevas integraciones: acepta el modelo de filtros/consultas más completo de `getVehicleEvents`.
</Note>

## Casos de uso

<CardGroup cols={2}>
  <Card title="Seguimiento de flotas y proveedores" icon="truck">
    Guarde las placas de su flota y de proveedores aprobados con el indicador `trust` y luego concílielas con los eventos de detección para confirmar llegadas puntuales.
  </Card>

  <Card title="Alertas de lista de vigilancia" icon="triangle-exclamation">
    Guarde las placas de interés con `alert: true` y combine las detecciones con webhooks para notificar a seguridad cuando se ve un vehículo marcado.
  </Card>

  <Card title="Análisis de estacionamiento y acceso" icon="chart-column">
    Use los informes por dispositivo para contar el tráfico diario o semanal de vehículos en una puerta o entrada de estacionamiento.
  </Card>

  <Card title="Investigación y auditoría" icon="magnifying-glass">
    Busque de forma aproximada una placa parcial de un incidente y luego exporte los eventos coincidentes como CSV para un informe.
  </Card>
</CardGroup>

## Solución de problemas

<AccordionGroup>
  <Accordion title="Mi filtro de tiempo no devuelve eventos">
    Confirme que está enviando **milisegundos de época**, no segundos, y que usa el nombre de campo correcto para el endpoint: `startTimeMs`/`endTimeMs` para `getVehicleEvents` y `export/vehicleEventsV2`, `startTime`/`endTime` para `searchLicensePlates`, y `timestampMs` para `getLicensePlatesByDevice`. Un valor en segundos se resolverá en 1970 y no devolverá nada.
  </Accordion>

  <Accordion title="Una placa que sé que fue vista no aparece en los resultados de búsqueda">
    Las lecturas de LPR pueden variar según la iluminación, el ángulo y la velocidad. Establezca `fuzzy: true` en `searchLicensePlates` para tolerar lecturas incorrectas de caracteres, y revise `matchingLicensePlates` y `partialLicensePlates` en los eventos devueltos para detectar coincidencias cercanas.
  </Accordion>

  <Accordion title="getVehicleEvents devuelve más de lo que esperaba">
    Recuerde que los campos de consulta (`nameQuery`, `licensePlateExactQuery`, `vehicleLabelQuery`, `licensePlateFuzzyQuery`, `unnamedQuery`) se combinan con O (OR): un evento solo tiene que coincidir con uno de ellos. Los campos de filtro (`deviceUuidFilter`, `locationUuidFilter`) se combinan con Y (AND). Reduzca los resultados moviendo criterios a los filtros o disminuyendo la cantidad de consultas.
  </Accordion>

  <Accordion title="No puedo ver la imagen de imageS3Key">
    `imageS3Key` y `thumbnailS3Key` son claves de almacenamiento S3, no URL que pueda abrir directamente. Use los endpoints de medios y grabaciones de Rhombus para obtener el contenido de la imagen de una clave dada.
  </Accordion>

  <Accordion title="reportVehicleEvent devuelve un error de permiso">
    Reportar una lectura incorrecta requiere el permiso `MANAGE_LICENSEPLATES` en su clave de API. La exportación CSV requiere `REPORT_ADMINISTRATION`. Genere o actualice su clave con los permisos necesarios en la Consola de Rhombus en Configuración > API.
  </Accordion>
</AccordionGroup>

## Próximos pasos

<CardGroup cols={2}>
  <Card title="Rostros y conteo de personas" icon="users" href="/es/implementations/faces-people-counting">
    Detecte e identifique personas, y cuente la ocupación junto con sus análisis de vehículos
  </Card>

  <Card title="Notificaciones por webhook" icon="webhook" href="/es/webhooks">
    Reciba notificaciones en tiempo real cuando se detecta un vehículo en la lista de vigilancia
  </Card>

  <Card title="Referencia de la API" icon="code" href="/api-reference/overview">
    Explore los esquemas completos de solicitud y respuesta de cada endpoint de vehículos
  </Card>
</CardGroup>
