# List Events

`GET /v2/events`

Core API v2, Events.

Retrieve a paginated list of what happened to one or more objects, in order — every recorded event of the payments, transactions, customers, subscriptions, invoices, products, prices or blacklist entries named in `subjectId`, whether or not a webhook was sent for it. This is how an activity timeline is built: pass a payment and its transactions to see it created, attempted at a processor and declined, sent to customer authentication and back, authorized, captured, refunded or voided, cancelled, charged back, including the failed captures and refunds recorded against its transactions. Each event carries the `type`, when it happened, the object it was recorded against, and a curated `details` object rather than the full event data. Sorted oldest first by default; pass `sortDirection=DESC` for newest first. Filter by `type` to leave out the event types you do not show — `type[nin][]=payment.updated`.

**Authentication:** Send `Authorization: Bearer <token>`. To authenticate, generate a Secret API Key from your ODUS Dashboard and include it in the `Authorization` header as follows: `Authorization: Bearer <YOUR_SECRET_API_KEY>`

## Parameters

### Query parameters

- `subjectId` (object or object, required): The objects whose events to list, by id — a payment, transaction, customer, subscription, invoice, product, price or blacklist entry (`pay_…`, `tx_…`, `cus_…`, `bl_…`, `sub_…`, `inv_…`, `prod_…`, `price_…`). Pass one with `subjectId[eq]` or several with `subjectId[in][]`, up to 100. Reading an object's events needs the permission that reads the object; a request naming an object you may not read is refused as a whole.
  - When the value is variant 1:
    - `eq` (string, required): Minimum length 1.
  - When the value is variant 2:
    - `in` (array of string, required): Minimum items 1. Maximum items 100. Each item: Minimum length 1.
- `type` (filter): Send as `type[<operator>]=<value>`. Operators: `eq`, `ne`, `in`, `nin`.
- `createdAt` (filter): Send as `createdAt[<operator>]=<value>`. Operators: `eq`, `ne`, `gt`, `gte`, `lt`, `lte`, `in`, `nin`.
- `sortDirection` (string): Sort direction. Defaults to ASC. One of `ASC`, `DESC`, `asc`, `desc`.
- `sortBy` (string): Field to sort by. Defaults to createdAt. One of `createdAt`.
- `limit` (number): Number of items per page. Defaults to 10, capped at 100. Send 0 to return no items, which is how you ask for "withTotal"'s count without fetching a page you do not need.
- `cursor` (string): Opaque cursor from a previous response ("nextCursor" or "prevCursor"). Send it back with the same "sortBy" and "sortDirection" — the cursor encodes them and a request that disagrees is rejected. "limit" may change between pages and simply changes the page size. Omit "cursor" for the first page.
- `withTotal` (boolean): Set to true to also return how many items match the filters, as "totalCount" in the response's pagination. The count ignores "cursor", so it does not change as you page — fetch it once per set of filters rather than on every page. Counting stops at 10000, above which "totalCountIsExact" is false. Omit this parameter to skip the count entirely.

## Responses

### `200`

OK

Type: object.

- `pagination` (object (CursorPageMetaDTO))
  - `mode` (string, required): Discriminator identifying cursor-based pagination metadata. One of `cursor`. Default `cursor`. Example: `cursor`.
  - `pageSize` (number, required): Number of items per page. Minimum 0. Example: `10`.
  - `hasNextPage` (boolean, required): Whether a next page exists. Example: `false`.
  - `hasPreviousPage` (boolean, required): Whether a previous page exists. Example: `true`.
  - `nextCursor` (string, required, nullable): Opaque cursor for fetching the next page. Null when there is no next page. Example: `eyJzIjoiY3JlYXRlZEF0IiwiZCI6ImFzYyIsIm4iOiJmb3J3YXJkIn0`.
  - `prevCursor` (string, required, nullable): Opaque cursor for fetching the previous page. Null when there is no previous page. Example: `eyJzIjoiY3JlYXRlZEF0IiwiZCI6ImFzYyIsIm4iOiJiYWNrd2FyZCJ9`.
  - `totalCount` (number): Number of items matching this request's filters, ignoring the cursor. Present only when the request sets "withTotal". Counting stops at 10000; read "totalCountIsExact" before showing this as a total. Example: `139`.
  - `totalCountIsExact` (boolean): Whether "totalCount" is the exact number of matching items. False when more items match than counting reaches, in which case "totalCount" holds that limit and should be shown as a lower bound, for example "over 10,000". Present only when the request sets "withTotal". Example: `true`.
- `data` (array of object (EventDTO))
  - `id` (string, required): ID of the event. Stable across reads. Example: `evt_2c9NxQ3jSVWpaAqEbTORrivRV20`.
  - `type` (string, required): What happened, named with the same vocabulary as the webhook event types: the object it concerns, then the change. One of `customer.created`, `customer.updated`, `blacklist.added`, `blacklist.removed`, `subscription.active`, `subscription.cancelled`, `subscription.updated`, `payment.created`, `payment.succeeded`, `payment.captured`, `payment.attempt_failed`, `payment.requires_action`, `payment.updated`, `payment.cancelled`, `payment.chargebacked`, `payment.reversed`, `transaction.reverse_failed`, `transaction.capture_failed`, `invoice.created`, `invoice.paid`, `invoice.voided`, `invoice.updated`, `product.created`, `product.updated`, `price.created`, `price.updated`, `price.deleted`. Example: `payment.captured`.
  - `createdAt` (string (date-time), required): When it happened. Example: `2024-02-18T12:00:00Z`.
  - `subjectType` (string, required): The kind of object the event was recorded against, read from the prefix of `subjectId`. A capture or refund that failed at the processor is recorded on the `transaction` that attempted it rather than on its payment. One of `payment`, `transaction`, `customer`, `blacklist`, `subscription`, `invoice`, `product`, `price`. Example: `payment`.
  - `subjectId` (string, required): ID of the object the event was recorded against. Example: `pay_2c9NxQ3jSVWpaAqEbTORrivRV20`.
  - `details` (map of string to (string or number or boolean or null), required, nullable): Curated context for the event, read from what it recorded. Which keys appear depends on `type`; every value is an id, an enum, an amount in minor units, an ISO 8601 date or a message safe to show. Populated for `payment.*` and `transaction.*` events — pass a payment and its transactions together as `subjectId[in][]` to read a payment’s whole history. `payment.created`: `amount`, `currency`, `initiator`, `captureMethod`, `customer`, `paymentMethod`. `payment.updated`: whichever of `amount`, `captureMethod`, `customer`, `paymentMethod` changed. `payment.requires_action`: `transaction`. `payment.attempt_failed`: `transaction` when the attempt reached a processor, `declineCode`, `declineType`, `message`. `payment.succeeded`: `transaction`, and `captureAt` when the capture is scheduled. `payment.captured` and `payment.reversed`: `amount` — the amount captured or refunded *by this event*, not the running total — and `transaction`. `payment.cancelled`: `cancellationReason`. Every payment event that names a `transaction`, and the two `transaction.*` types, also carry what that transaction went through, as it is now: `gatewayProfile`, `gatewayProfileTitle` and `integration` for the processor; `paymentMethod` and `paymentMethodType`, with `cardBrand` and `cardLastFour` for a card and `applePayDisplayName` for Apple Pay. These are omitted when the transaction can no longer be read. `null` when the event carries no context — always for `payment.chargebacked`, and for every event of a customer, subscription, invoice, product, price or blacklist entry, whose `details` are not yet projected.

### `202`

The merchant is entitled but its environment is not provisioned yet. Provisioning has been kicked off (exactly once) and is in progress; retry the request — it succeeds once the environment is ready. Returned only for identity-token (dashboard) requests bound to a merchant, not for secret-key API calls; any such endpoint can return it while provisioning is underway.

Type: object (ProvisioningInProgress).

- `status` (string, required): Signals the merchant environment is still being provisioned. One of `provisioning`.
- `merchantAccountId` (string, required): The merchant account whose environment is being provisioned. Example: `dAI3aa87ROOeupeBCjNSKCOBOisBCYjB`.

### Errors

- `400`: The request was rejected. `type` is `invalid_request_error` when the request itself is at fault — `errors` then lists every problem found, with field-attributable entries prefixed by the field’s path; or `invalid_state_error` when the request was well-formed but the resource is not in a state that allows it.
- `401`: No API key was supplied, or the key is not valid. `type` is `authentication_error`.
- `403`: The API key is valid but lacks the permission this operation requires. `type` is `permission_error`.
- `429`: Too many requests. A limit applies per operation; requests to other operations are unaffected. `type` is `rate_limit_error`. Use the `Retry-After-global` header to know when to retry.
- `500`: The request could not be completed because of an unexpected error. `type` is `api_error`.
- `503`: The request could not be served right now: the API is temporarily at capacity, or a dependency needed to authorize the request is unavailable — the auth service that verifies credentials, or the entitlement lookup behind it. `type` is `api_error`. It is raised before the operation runs, so the request had no effect, and unlike a plain 500 the condition is transient: retry with backoff.
- `504`: The request exceeded the processing time limit and was abandoned. `type` is `api_error` and `code` is `timeout` — unlike a plain 500 the request may still have taken effect, so retry with the same idempotency key rather than blindly.

Every error response has the same body: see [Errors](https://docs.odus.com/docs/guides/api-features/errors.md).

---

Generated from the Core API v2 OpenAPI document, https://api.odus.com/openapi.v2.json. Interactive page: https://docs.odus.com/docs/api/core/v2/event-controller-find-all-paginated
