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

# The Activity Event object

> One envelope for everything that happened: career activity, skill activity and identity-provider events

<Info>
  **Quick Summary:** SkillsDB keeps three append-only activity logs. All three share one envelope — what happened, when, who did it, what it relates to — with documented per-scope extras. Activity endpoints live with the object they describe; this page defines the shape, filters and pagination they all share.
</Info>

## The envelope

Every activity event, on every scope, carries:

| Field           | Type           | Description                                                                                          |
| --------------- | -------------- | ---------------------------------------------------------------------------------------------------- |
| `id`            | string         | Opaque entry id                                                                                      |
| `event`         | string \| null | Event type, lowercase snake                                                                          |
| `description`   | string \| null | Human-readable summary                                                                               |
| `performedById` | string \| null | Person who performed the change — `null` when the change did not originate from a person in SkillsDB |
| `performedAt`   | string \| null | When it happened (UTC)                                                                               |

## The three scopes

| Scope             | Endpoint                               | Scope required | Event types                                                                                         | Extras                                                                                                                                               |
| ----------------- | -------------------------------------- | -------------- | --------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
| Career            | `GET /api/v1/careers/{id}/activity`    | `careers:read` | \~40 — lifecycle, settings, skills, sections, levels, groups, learnings, assignments, labels, flags | `emailSent`, `relatedPersonId`, `relatedSkillId`, `relatedSectionId`, `relatedLevelId`, `bulkGroupId`                                                |
| Skill             | `GET /api/v1/skills/{id}/activity`     | `skills:read`  | exactly 3 — `baseline`, `version_created`, `renew_training`. A version log, not a change feed       | `versionId`, `affectedUserCount`, `renewalOption`                                                                                                    |
| Identity provider | `GET /api/v1/identity-provider-events` | `people:read`  | 13 — group lifecycle, user provisioning, permission changes, career assignment, membership          | `oldValue`, `newValue`, `payloadSummary`, `source`, `externalMemberId`, `relatedPersonId`, `relatedPersonName`, `relatedGroupId`, `relatedGroupName` |

The identity-provider scope is the only one recording changes SkillsDB did **not** originate — which is exactly what to check when data appears to change by itself — and the only one carrying before-and-after values. Its `performedById` is always `null`: the performer is the identity provider. It is also company-scoped rather than per-object, since provisioning events concern the whole tenant.

## Shared filters

All three scopes take the same filter set — `event`, `from`, `to`, `performedBy`, `relatedPersonId` — with the standard pagination (`limit` up to 200, `offset` up to 10,000). A filter a scope cannot support is **rejected** with a [validation error](/api-docs/errors/validation-error), never silently ignored:

* The skill log records no related person → `relatedPersonId` is rejected there.
* Identity-provider events have no SkillsDB performer → `performedBy` is rejected there.
* The career log supports the full set, plus `bulkGroupId` to group the rows of one bulk operation.

An unknown `event` value is likewise a validation error rather than an empty page, so a typo never reads as "no activity".

## What is deliberately not here

* **A company-wide change feed.** Career and skill logs are scoped to one object; polling per object plus the identity-provider stream is the nearest v1 offers. The shared envelope is what makes a tenant-wide feed a later filter change rather than a new contract.
* **Import runs.** An import is a job with a status and a result, not an event — it does not fit this envelope and is deferred from v1.
* **Row-level history tables.** Internal audit exhaust, not an integration surface.
