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

# The Activity Log object

> One recorded action in your organization, the fields each entry carries, and how to read the log reliably from a log shipper.

An activity log entry records one action in your organization. It says who took it (`actor`), what it
touched (`targets`), what kind of action it was (`event_type`), and how it ended (`outcome`). An
admin who changes a user's Lumos roles, and a user who disconnects an app, each produce an entry.

The log is read-only. You read it through one endpoint,
[List Activity Logs](https://docs.lumos.com/api-reference/v1/activity-logs/list-activity-logs.md).

```json The Activity Log object theme={null}
{
  "event_hash": "b01c7e7c24c786b087ae1121a0cb1640da2aaf65060b471ebf0b6e3df81d18020fca6d495c8852b365b467aa5215615dd4503855dcdccca0d1955ed62f7289d7",
  "event_type": "ADMIN_DISCONNECTS_INTEGRATION",
  "event_type_user_friendly": "A user attempted to disconnect an integration",
  "outcome": "Succeeded",
  "targets": [
    { "target_type": "App class", "app_id": "okta.com", "name": "Okta" }
  ],
  "actor": {
    "actor_type": "Lumos user",
    "email": "jane.smith@example.com",
    "given_name": "Jane",
    "family_name": "Smith"
  },
  "event_began_at": "2026-09-24T18:02:11Z",
  "event_metadata": {}
}
```

## Attributes

| Field | Type | Description |
| - | - | - |
| `event_hash` | string | A hash that identifies the entry. No two entries share one, so it works as a deduplication key. Always present. |
| `event_type` | string | The action's machine-readable name, such as `ADMIN_DISCONNECTS_INTEGRATION`. Always present. |
| `event_type_user_friendly` | string | A sentence describing the action, such as "A user attempted to disconnect an integration". Empty when the action has no description. Always present. |
| `outcome` | string | How the action ended: `Succeeded`, `Failed`, or `Invalid or Misconfigured Action`. Always present. |
| `targets` | array | What the action touched. Each item has a `target_type` plus that target's fields. Always present. |
| `actor` | object | Who or what took the action, as an `actor_type` plus that actor's fields. Always present. |
| `event_began_at` | string or null | When Lumos detected that the action began, as ISO 8601 in UTC with a `Z` suffix. |
| `event_metadata` | object | Details that depend on the action, such as `business_justification` or `error_message`. Only keys with a value appear. Always present. |

## Actors and targets

`actor`, and each item in `targets`, has a type field (`actor_type` or `target_type`) and the fields
of the thing it names. A Lumos user has `email`, `given_name`, and `family_name`. An app class has
`app_id` and `name`. The fields depend on the type, so read the type before you read the rest. When
Lumos can't find the underlying record, only the type is present.

## Who can read the log

Of the built-in roles, Admin and Read Only Admin can read the whole log. Auditor and AppStore Read
Only Admin can read their own product area's entries by sending `product_area=ACCESS_REVIEW` or
`product_area=APP_STORE`. Without `product_area`, or with an area your role can't read, the call
returns `403`.
[Migrate activity logs and identity events](https://docs.lumos.com/reference/v1/migrate/activity-logs-and-identity-events.md)
covers what this means for these roles.

`product_area` limits the list to one product area's entries: `APP_STORE`, `ACCESS_REVIEW`,
`VENDORS`, or `OTHER`. When you send `product_area`, entries that belong to no product area don't
appear.

## The time window

`since` and `until` bound the list, and both are inclusive. Lumos reads either one without a UTC
offset as UTC. If you omit them, the window is the last seven days, and Lumos recomputes it on every
request. That default is fine for a single page.

When you read several pages, send both `since` and `until` so that the set of entries doesn't
change between pages. A page token continues only the sequence of pages it came from, so send the
same `since` and `until` with it.

The window selects entries by when their action finished. Lumos sorts the list by `event_began_at`,
newest first, so an entry can have an `event_began_at` earlier than `since`.

```bash theme={null}
curl -s 'https://api.lumos.com/v1/activity-logs?since=2026-09-24T00:00:00&until=2026-09-24T01:00:00&page_size=100' \
  --header 'Authorization: Bearer lsk_your_token'
```

## Reading the log from a log shipper

To poll [List Activity Logs](https://docs.lumos.com/api-reference/v1/activity-logs/list-activity-logs.md) from a log shipper
such as Elastic Filebeat's `httpjson` input or Cribl, follow these steps. They read the log in time
windows and page through each one:

1. Poll in windows with explicit `since` and `until`.
2. For each page, send the previous response's `next_page_token` as `page_token`, with the same
   `since` and `until`.
3. Stop when `next_page_token` is missing or `null`.
4. Start each window 5 minutes before the previous `until`, so consecutive windows overlap.
5. Drop entries whose `event_hash` you've already seen.

`page_size` can be up to 100.

The overlap and the deduplication cover two cases. Both ends of a window are inclusive, so an entry
that finished exactly on a boundary appears in two windows. Deduplication drops the second copy.
An entry can appear 30 seconds to several minutes after its action finishes, so it can arrive after
you've read its window. The overlap lets the next window read it.

**Filebeat.** In the `httpjson` input, `response.split` with a `target` of `body.activity_logs`
makes each entry its own Filebeat event. `response.pagination` can set the `url.params.page_token`
target from the last response's `next_page_token`, and `request.transforms` can set the
`Authorization` header.

**Cribl.** A REST Collector's Response Body Attribute pagination reads the next page's position
from an attribute of the response body, here `next_page_token`. Check how your REST Collector sends
that value on the next request. Lumos reads the page token only from the `page_token` query
parameter. A page token sent under another name returns `400`.

## Endpoints

| Endpoint | Path |
| - | - |
| [List Activity Logs](https://docs.lumos.com/api-reference/v1/activity-logs/list-activity-logs.md) | `GET /v1/activity-logs` |
