# List an employee's access events

Requires the `employee:read` scope.

`GET /employees/{id}/access-history`

Scope `employee:read`

Requires the `employee:read` scope.

## Path parameters

| Name | Type | Required | Description |
|---|---|---|---|
| `id` | string | yes |  |

## Query parameters

| Name | Type | Required | Description |
|---|---|---|---|
| `limit` | integer | no | Page size. minimum 1, maximum 100, default 25 |
| `offset` | integer | no | Rows to skip (offset mode). Cannot be combined with cursor. minimum 0, maximum 10000, default 0 |
| `cursor` | string | no | An opaque cursor taken from meta.nextCursor of the previous page (cursor mode). Valid for 24 hours and bound to the token and the query; do not parse or construct it. |
| `sort[eventId]` | string | no | Sort direction for eventId. One of `asc`, `desc`. |
| `sort[occurredAt]` | string | no | Sort direction for occurredAt. One of `asc`, `desc`. |
| `filter[assetId][eq]` | string | no | Filter assetId (eq). |
| `filter[assetId][in]` | string | no | Filter assetId (in). Comma-separated, at most 50 values. |
| `filter[eventId][eq]` | string | no | Filter eventId (eq). |
| `filter[eventId][in]` | string | no | Filter eventId (in). Comma-separated, at most 50 values. |
| `filter[eventType][eq]` | string | no | Filter eventType (eq). One of `DETECTED`, `REVOKED`, `VERIFIED`. |
| `filter[eventType][in]` | string | no | Filter eventType (in). Comma-separated, at most 50 values. |
| `filter[occurredAt][gte]` | string (date-time) | no | Filter occurredAt (gte). |
| `filter[occurredAt][lt]` | string (date-time) | no | Filter occurredAt (lt). |

## Returns

The `data` field of the standard `{ data, error, meta }` envelope:

An array of object:
- `assetId`: string Asset id, always ast_ (a legacy row's 24-hex id is returned as ast_<hex>).
- `assetLegacyId`: optional string The legacy 24-hex asset id; present only for legacy rows.
- `employeeId`: string Employee (empl_ FlakeID).
- `eventId`: string Access event id (ace_ FlakeID); the keyset tie-break. Empty for legacy events.
- `eventType`: string DETECTED, REVOKED or VERIFIED.
- `occurredAt`: string (date-time) When the audit observed the event (events are append-only; the sync field).
- No other fields.

## Errors

| Status | Code | Retry | Meaning |
|---|---|---|---|
| 400 | - | no | The request is invalid. |
| 401 | - | no | The token is missing, malformed, expired or revoked. |
| 402 | - | no | The organisation's plan does not include the feature this route needs. |
| 403 | - | no | The token may not use this route. |
| 404 | - | no | The resource does not exist in this organisation. |
| 429 | - | yes | Rate limit or row budget exceeded; retry after the time in Retry-After. |
| 500 | - | no | Unexpected server error. |
| 503 | - | yes | A dependency is temporarily unavailable; retry later. |

## Example

### curl

```bash
curl "https://api.autociso.io/api/v1/employees/<id>/access-history" \
  -H "Authorization: Bearer <your-api-token>"
```

### Python

```python
import requests

response = requests.get(
    "https://api.autociso.io/api/v1/employees/<id>/access-history",
    headers={"Authorization": "Bearer <your-api-token>"},
)
print(response.json())
```

### JavaScript

```javascript
const response = await fetch("https://api.autociso.io/api/v1/employees/<id>/access-history", {
  method: "GET",
  headers: { "Authorization": "Bearer <your-api-token>" },
});
console.log(await response.json());
```

## Response (200)

```json
{
  "data": [
    {
      "assetId": "ast_1hfz2m3r9t5b",
      "employeeId": "empl_1hgyv08q3k2m",
      "eventId": "ace_1hk1d4q8s2wv",
      "eventType": "DETECTED",
      "occurredAt": "2026-01-15T08:00:00Z"
    },
    {
      "assetId": "ast_1hfz2m3r9t5b",
      "employeeId": "empl_1hgyv08q3k2m",
      "eventId": "ace_1hk3x0m5t7yc",
      "eventType": "REVOKED",
      "occurredAt": "2026-09-02T02:00:00Z"
    }
  ],
  "error": null,
  "meta": {
    "limit": 25,
    "offset": 0,
    "total": 2
  }
}
```
