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

# Listar dispositivos de una entidad

> Obtener todos los dispositivos de una entidad — para fingerprinting de dispositivos y prevención de fraude en gu1, con ejemplos para list.

## Resumen

Recupera todos los dispositivos registrados para una entidad específica, ordenados por última actividad. Usa este endpoint para monitorear patrones de uso de dispositivos, detectar acceso sospechoso y construir reglas de detección de fraude basadas en dispositivos.

## Endpoint

```
GET https://api.gu1.ai/devices/entity/{entityId}
```

## Autenticación

Requiere una clave API válida en el encabezado Authorization:

```bash theme={null}
Authorization: Bearer YOUR_API_KEY
```

## Parámetros de Ruta

<ParamField path="entityId" type="string" required>
  UUID de la entidad cuyos dispositivos deseas recuperar
</ParamField>

## Parámetros de Consulta

<ParamField query="limit" type="number" default="50">
  Número máximo de dispositivos a devolver por página (máx: 1000)

  Ejemplo: `?limit=100`
</ParamField>

<ParamField query="offset" type="number" default="0">
  Número de dispositivos a omitir para paginación

  Ejemplo: `?offset=50`
</ParamField>

## Respuesta

<ResponseField name="success" type="boolean">
  Indica si la solicitud fue exitosa
</ResponseField>

<ResponseField name="devices" type="array">
  Array de objetos de dispositivo ordenados por `lastSeenAt` (más reciente primero)

  <ResponseField name="devices[].id" type="string">
    UUID interno del dispositivo de gu1
  </ResponseField>

  <ResponseField name="devices[].deviceId" type="string">
    Identificador del dispositivo
  </ResponseField>

  <ResponseField name="devices[].externalId" type="string">
    Identificador externo del dispositivo
  </ResponseField>

  <ResponseField name="devices[].entityId" type="string">
    UUID de la entidad asociada
  </ResponseField>

  <ResponseField name="devices[].entityExternalId" type="string">
    ID externo de la entidad (desnormalizado)
  </ResponseField>

  <ResponseField name="devices[].entityTaxId" type="string">
    Tax ID de la entidad (desnormalizado)
  </ResponseField>

  <ResponseField name="devices[].deviceName" type="string">
    Nombre del dispositivo definido por el usuario o nombre del hardware
  </ResponseField>

  <ResponseField name="devices[].deviceDetails" type="object">
    Metadatos adicionales del dispositivo (objeto JSON). Detalles por plataforma.
  </ResponseField>

  <ResponseField name="devices[].platform" type="string">
    Plataforma del dispositivo (android, ios, web)
  </ResponseField>

  <ResponseField name="devices[].manufacturer" type="string">
    Fabricante del dispositivo
  </ResponseField>

  <ResponseField name="devices[].model" type="string">
    Modelo del dispositivo
  </ResponseField>

  <ResponseField name="devices[].brand" type="string">
    Marca del dispositivo
  </ResponseField>

  <ResponseField name="devices[].osName" type="string">
    Nombre del sistema operativo
  </ResponseField>

  <ResponseField name="devices[].osVersion" type="string">
    Versión del sistema operativo
  </ResponseField>

  <ResponseField name="devices[].browser" type="string">
    Nombre del navegador (solo web)
  </ResponseField>

  <ResponseField name="devices[].browserVersion" type="string">
    Versión del navegador (solo web)
  </ResponseField>

  <ResponseField name="devices[].latitude" type="number">
    Latitud geográfica
  </ResponseField>

  <ResponseField name="devices[].longitude" type="number">
    Longitud geográfica
  </ResponseField>

  <ResponseField name="devices[].city" type="string">
    Nombre de la ciudad
  </ResponseField>

  <ResponseField name="devices[].region" type="string">
    Estado/provincia
  </ResponseField>

  <ResponseField name="devices[].country" type="string">
    Nombre del país
  </ResponseField>

  <ResponseField name="devices[].countryCode" type="string">
    Código de país ISO
  </ResponseField>

  <ResponseField name="devices[].ipAddress" type="string">
    Última dirección IP conocida
  </ResponseField>

  <ResponseField name="devices[].isEmulator" type="boolean">
    Si el dispositivo es un emulador
  </ResponseField>

  <ResponseField name="devices[].isRooted" type="boolean">
    Si el dispositivo está rooteado/jailbreakeado
  </ResponseField>

  <ResponseField name="devices[].isBlocked" type="boolean">
    Si el dispositivo está bloqueado
  </ResponseField>

  <ResponseField name="devices[].isTrusted" type="boolean">
    Si el dispositivo es confiable
  </ResponseField>

  <ResponseField name="devices[].firstSeenAt" type="string">
    Marca de tiempo de primera vez visto (ISO 8601)
  </ResponseField>

  <ResponseField name="devices[].lastSeenAt" type="string">
    Marca de tiempo de última vez visto (ISO 8601)
  </ResponseField>

  <ResponseField name="devices[].createdAt" type="string">
    Marca de tiempo de creación
  </ResponseField>

  <ResponseField name="devices[].updatedAt" type="string">
    Marca de tiempo de última actualización
  </ResponseField>
</ResponseField>

<ResponseField name="pagination" type="object">
  Información de paginación

  <ResponseField name="pagination.total" type="number">
    Número total de dispositivos para esta entidad
  </ResponseField>

  <ResponseField name="pagination.limit" type="number">
    Límite de tamaño de página usado
  </ResponseField>

  <ResponseField name="pagination.offset" type="number">
    Desplazamiento usado
  </ResponseField>

  <ResponseField name="pagination.hasMore" type="boolean">
    Si hay más páginas disponibles
  </ResponseField>
</ResponseField>

## Ejemplos

### Consulta Básica

<CodeGroup>
  ```bash cURL theme={null}
  curl https://api.gu1.ai/devices/entity/550e8400-e29b-41d4-a716-446655440000 \
    -H "Authorization: Bearer YOUR_API_KEY"
  ```

  ```javascript JavaScript theme={null}
  const response = await fetch(
    'https://api.gu1.ai/devices/entity/550e8400-e29b-41d4-a716-446655440000',
    {
      headers: {
        'Authorization': 'Bearer YOUR_API_KEY'
      }
    }
  );

  const data = await response.json();
  console.log(data.devices);
  ```

  ```python Python theme={null}
  import requests

  response = requests.get(
      'https://api.gu1.ai/devices/entity/550e8400-e29b-41d4-a716-446655440000',
      headers={
          'Authorization': 'Bearer YOUR_API_KEY'
      }
  )

  data = response.json()
  print(data['devices'])
  ```
</CodeGroup>

### Con Paginación

<CodeGroup>
  ```bash cURL theme={null}
  curl "https://api.gu1.ai/devices/entity/550e8400-e29b-41d4-a716-446655440000?limit=20&offset=0" \
    -H "Authorization: Bearer YOUR_API_KEY"
  ```

  ```javascript JavaScript theme={null}
  const response = await fetch(
    'https://api.gu1.ai/devices/entity/550e8400-e29b-41d4-a716-446655440000?limit=20&offset=0',
    {
      headers: {
        'Authorization': 'Bearer YOUR_API_KEY'
      }
    }
  );

  const data = await response.json();
  console.log(`Página 1 de ${Math.ceil(data.pagination.total / 20)} páginas`);
  ```

  ```python Python theme={null}
  import requests

  response = requests.get(
      'https://api.gu1.ai/devices/entity/550e8400-e29b-41d4-a716-446655440000',
      headers={'Authorization': 'Bearer YOUR_API_KEY'},
      params={'limit': 20, 'offset': 0}
  )

  data = response.json()
  print(f"Página 1 de {data['pagination']['total'] // 20 + 1} páginas")
  ```
</CodeGroup>

## Ejemplo de Respuesta

```json theme={null}
{
  "success": true,
  "devices": [
    {
      "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
      "deviceId": "840e89e4d46efd67",
      "externalId": "840e89e4d46efd67",
      "entityId": "550e8400-e29b-41d4-a716-446655440000",
      "entityExternalId": "user_12345",
      "entityTaxId": "20-12345678-9",
      "deviceName": "Galaxy A15",
      "deviceDetails": {},
      "platform": "android",
      "manufacturer": "samsung",
      "model": "SM-A156M",
      "brand": "samsung",
      "osName": "Android",
      "osVersion": "Android 16",
      "browser": null,
      "browserVersion": null,
      "latitude": -34.6037,
      "longitude": -58.3816,
      "city": "Buenos Aires",
      "region": "Buenos Aires",
      "country": "Argentina",
      "countryCode": "AR",
      "ipAddress": "10.40.64.231",
      "isEmulator": false,
      "isRooted": false,
      "isBlocked": false,
      "isTrusted": true,
      "firstSeenAt": "2026-01-20T10:00:00Z",
      "lastSeenAt": "2026-01-30T14:30:00Z",
      "createdAt": "2026-01-20T10:00:00Z",
      "updatedAt": "2026-01-30T14:30:00Z"
    },
    {
      "id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
      "deviceId": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
      "externalId": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
      "entityId": "550e8400-e29b-41d4-a716-446655440000",
      "entityExternalId": "user_12345",
      "entityTaxId": null,
      "deviceName": null,
      "deviceDetails": {},
      "platform": "web",
      "manufacturer": null,
      "model": null,
      "brand": null,
      "osName": "Windows",
      "osVersion": null,
      "browser": "Chrome",
      "browserVersion": "120.0.6099.129",
      "latitude": -34.6037,
      "longitude": -58.3816,
      "city": "Buenos Aires",
      "region": "Buenos Aires",
      "country": "Argentina",
      "countryCode": "AR",
      "ipAddress": "10.40.64.231",
      "isEmulator": false,
      "isRooted": false,
      "isBlocked": false,
      "isTrusted": false,
      "firstSeenAt": "2026-01-25T08:15:00Z",
      "lastSeenAt": "2026-01-30T12:00:00Z",
      "createdAt": "2026-01-25T08:15:00Z",
      "updatedAt": "2026-01-30T12:00:00Z"
    }
  ],
  "pagination": {
    "total": 5,
    "limit": 50,
    "offset": 0,
    "hasMore": false
  }
}
```

## Respuestas de Error

### 401 Unauthorized

```json theme={null}
{
  "success": false,
  "error": {
    "code": "UNAUTHORIZED",
    "message": "Invalid or missing API key"
  }
}
```

### 403 Forbidden

```json theme={null}
{
  "success": false,
  "error": {
    "code": "FORBIDDEN",
    "message": "Insufficient permissions to read devices"
  }
}
```

### 404 Not Found

```json theme={null}
{
  "success": false,
  "error": {
    "code": "ENTITY_NOT_FOUND",
    "message": "Entity with ID 550e8400-e29b-41d4-a716-446655440000 not found"
  }
}
```

### 500 Internal Server Error

```json theme={null}
{
  "success": false,
  "error": {
    "code": "DEVICES_FETCH_FAILED",
    "message": "Failed to fetch entity devices"
  }
}
```

## Casos de Uso

### Panel de Inventario de Dispositivos

Construye un panel mostrando todos los dispositivos usados por tus entidades:

```javascript theme={null}
async function getDeviceInventory(entityId) {
  const response = await fetch(
    `https://api.gu1.ai/devices/entity/${entityId}`,
    {
      headers: { 'Authorization': `Bearer ${API_KEY}` }
    }
  );

  const data = await response.json();

  // Agrupar por plataforma
  const byPlatform = data.devices.reduce((acc, device) => {
    acc[device.platform] = (acc[device.platform] || 0) + 1;
    return acc;
  }, {});

  console.log('Dispositivos por plataforma:', byPlatform);
  return data.devices;
}
```

### Detección de Fraude

Detecta patrones de dispositivos sospechosos:

```javascript theme={null}
async function detectSuspiciousDevices(entityId) {
  const response = await fetch(
    `https://api.gu1.ai/devices/entity/${entityId}`,
    {
      headers: { 'Authorization': `Bearer ${API_KEY}` }
    }
  );

  const data = await response.json();

  // Marcar dispositivos sospechosos
  const suspicious = data.devices.filter(device =>
    device.isEmulator ||
    device.isRooted ||
    device.isBlocked
  );

  if (suspicious.length > 0) {
    console.warn('Dispositivos sospechosos encontrados:', suspicious);
  }

  return suspicious;
}
```

### Análisis Geográfico

Analiza ubicaciones de dispositivos para anomalías:

```javascript theme={null}
async function analyzeDeviceLocations(entityId) {
  const response = await fetch(
    `https://api.gu1.ai/devices/entity/${entityId}`,
    {
      headers: { 'Authorization': `Bearer ${API_KEY}` }
    }
  );

  const data = await response.json();

  // Obtener países únicos
  const countries = new Set(
    data.devices.map(d => d.countryCode).filter(Boolean)
  );

  // Marcar si hay dispositivos de múltiples países
  if (countries.size > 1) {
    console.warn('Dispositivos desde múltiples países:', Array.from(countries));
  }

  return Array.from(countries);
}
```

### Monitoreo de Actividad

Monitorea actividad reciente de dispositivos:

```javascript theme={null}
async function getRecentDevices(entityId, hours = 24) {
  const response = await fetch(
    `https://api.gu1.ai/devices/entity/${entityId}`,
    {
      headers: { 'Authorization': `Bearer ${API_KEY}` }
    }
  );

  const data = await response.json();
  const cutoff = new Date(Date.now() - hours * 60 * 60 * 1000);

  // Filtrar dispositivos activos en las últimas N horas
  const recentDevices = data.devices.filter(device =>
    new Date(device.lastSeenAt) > cutoff
  );

  console.log(`${recentDevices.length} dispositivos activos en las últimas ${hours} horas`);
  return recentDevices;
}
```

## Mejores Prácticas de Paginación

### Iterar a Través de Todas las Páginas

```javascript theme={null}
async function getAllDevices(entityId) {
  const allDevices = [];
  let offset = 0;
  const limit = 100;
  let hasMore = true;

  while (hasMore) {
    const response = await fetch(
      `https://api.gu1.ai/devices/entity/${entityId}?limit=${limit}&offset=${offset}`,
      {
        headers: { 'Authorization': `Bearer ${API_KEY}` }
      }
    );

    const data = await response.json();
    allDevices.push(...data.devices);

    hasMore = data.pagination.hasMore;
    offset += limit;
  }

  console.log(`Total de dispositivos: ${allDevices.length}`);
  return allDevices;
}
```

## Próximos Pasos

<CardGroup cols={2}>
  <Card title="Crear Dispositivo" icon="plus" href="/es/api-reference/devices/create">
    Registrar un nuevo dispositivo
  </Card>

  <Card title="API de Eventos" icon="bolt" href="/es/api-reference/events/overview">
    Aprende sobre registro automático de dispositivos
  </Card>

  <Card title="Detección de Fraude" icon="shield-check" href="/es/use-cases/transaction-monitoring/fraud-detection">
    Construye reglas de fraude basadas en dispositivos
  </Card>

  <Card title="Matriz de Riesgo" icon="table-cells" href="/es/api-reference/risk-matrix/list">
    Configura puntuación de riesgo con datos de dispositivos
  </Card>
</CardGroup>
