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

# Has events by entity

> Fast boolean check whether an entity has any linked user events — same linkage scope as list-by-entity without returning event rows or counts.

## Overview

Use this endpoint when you only need to know **if** an entity has user events (for UI badges, tab visibility, or preflight checks), not the full timeline. It uses the **same matching scope** as [List by Entity](/en/api-reference/events/list-by-entity): `entity_id`, `entity_external_id`, or `tax_id` within your organization.

<Tip>
  Prefer this endpoint over listing events with `limit=1` when you only need a yes/no answer — it avoids `COUNT(*)`, sorting, and serializing event payloads.
</Tip>

<Note>
  **Entity identifiers:** you can query by query parameter without the internal UUID. Lookup priority: `entity_id` → `entity_external_id` → `tax_id` (when multiple are sent, the highest-priority wins). For `tax_id`, the DB comparison normalizes non-alphanumeric characters (e.g. `20-24245549-6` and `20242455496`).

  The legacy route `GET …/entity/{entityId}/has-events` remains available when you already have the UUID.
</Note>

## Performance

Designed for low latency:

| Aspect      | Behavior                                                                                                                                                                            |
| ----------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Queries** | Two round trips: entity lookup + one `LIMIT 1` probe on `user_events`                                                                                                               |
| **No**      | `COUNT(*)`, `ORDER BY`, pagination, or full event / metadata columns in the response                                                                                                |
| **Indexes** | `organization_id` + `entity_id` uses `idx_user_events_organization_entity_id`; `entity_external_id` and `tax_id` use dedicated indexes when the OR branch matches those identifiers |

Typical latency is dominated by network and auth, not by scanning large event histories.

## Endpoint

```
GET https://api.gu1.ai/events/user/entity/has-events
```

## Authentication

Requires a valid API key in the Authorization header:

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

## Query Parameters

At least **one** is required. If you send multiple, priority is `entity_id` → `entity_external_id` → `tax_id`.

<ParamField query="entity_id" type="string">
  Entity UUID (highest priority)

  Example: `?entity_id=550e8400-e29b-41d4-a716-446655440000`
</ParamField>

<ParamField query="entity_external_id" type="string">
  Your external entity identifier

  Example: `?entity_external_id=user_12345`
</ParamField>

<ParamField query="tax_id" type="string">
  Tax ID (CUIT/CUIL/CPF/CNPJ, etc.). Exact and normalized match (alphanumeric only)

  Example: `?tax_id=20242455496`
</ParamField>

## Response

<ResponseField name="success" type="boolean">
  Indicates if the request was successful
</ResponseField>

<ResponseField name="hasEvents" type="boolean">
  `true` if at least one user event is linked to this entity (same scope as list-by-entity); otherwise `false`
</ResponseField>

<ResponseField name="entityId" type="string">
  Resolved internal entity UUID (useful when you queried by `entity_external_id` or `tax_id`)
</ResponseField>

### Example — has events

```json theme={null}
{
  "success": true,
  "hasEvents": true,
  "entityId": "550e8400-e29b-41d4-a716-446655440000"
}
```

### Example — no events

```json theme={null}
{
  "success": true,
  "hasEvents": false,
  "entityId": "550e8400-e29b-41d4-a716-446655440000"
}
```

## Errors

| Status | Code               | When                                                          |
| ------ | ------------------ | ------------------------------------------------------------- |
| 400    | —                  | No entity identifier provided in query                        |
| 404    | `ENTITY_NOT_FOUND` | Entity does not exist in your organization or is soft-deleted |
| 401    | —                  | Missing or invalid API key                                    |
| 403    | —                  | Insufficient permissions (`events:read`)                      |

## Examples

```bash theme={null}
# By external ID (typical when you don't have the internal UUID)
curl "https://api.gu1.ai/events/user/entity/has-events?entity_external_id=user_12345" \
  -H "Authorization: Bearer YOUR_API_KEY"

# By tax ID
curl "https://api.gu1.ai/events/user/entity/has-events?tax_id=20242455496" \
  -H "Authorization: Bearer YOUR_API_KEY"

# Legacy: UUID in path
curl "https://api.gu1.ai/events/user/entity/550e8400-e29b-41d4-a716-446655440000/has-events" \
  -H "Authorization: Bearer YOUR_API_KEY"
```

```javascript theme={null}
const res = await fetch(
  'https://api.gu1.ai/events/user/entity/has-events?entity_external_id=user_12345',
  { headers: { Authorization: `Bearer ${API_KEY}` } }
);
const { hasEvents, entityId } = await res.json();
if (hasEvents) {
  const timeline = await fetch(
    `https://api.gu1.ai/events/user/entity/${entityId}?limit=50`,
    { headers: { Authorization: `Bearer ${API_KEY}` } }
  );
}
```

## Next Steps

<CardGroup cols={2}>
  <Card title="List by Entity" icon="list" href="/en/api-reference/events/list-by-entity">
    Full event timeline when `hasEvents` is true
  </Card>

  <Card title="List Events" icon="filter" href="/en/api-reference/events/list">
    Query events with filters
  </Card>

  <Card title="Event Statistics" icon="chart-bar" href="/en/api-reference/events/stats">
    Aggregated counts by event type
  </Card>

  <Card title="Events Overview" icon="book" href="/en/api-reference/events/overview">
    User events API overview
  </Card>
</CardGroup>
