Audit logs
Query the immutable audit trail Tokeflow keeps for every change and access event — who did what, to which resource, when, from where, and with what outcome.
Every state change and sensitive access in Tokeflow writes an audit log entry — an append-only record of who did what to which resource. Each entry captures the actor (a dashboard user, an API key, the system, or a provider webhook), the action performed, the affected entity, the state before and after the change, the client IP address, and whether the operation succeeded or failed.
Audit logs are read-only through the API: you can list and filter them, but never create, modify, or delete them. Use them to answer "who changed this connector?", to reconstruct the history of an order or a routing profile, or to feed your own SIEM and compliance reporting pipelines. The outcome field records event success or failure in line with PCI DSS 10.3.1.
Results are scoped by the API key you authenticate with:
Merchant keys return audit logs for that merchant only. Organization keys return audit logs across the entire organization — pass the optional merchant_id query parameter to drill down into a specific merchant. Sending merchant_id with a Merchant key is a no-op; it is ignored.
The audit log object
| Field | Type | Description |
|---|---|---|
id | string | Audit log ID (UUID). |
organization_id | string | null | Organization the event belongs to. |
merchant_id | string | null | Merchant the event belongs to. Null for organization-level events. |
entity_type | string | Type of entity affected. See Entity types. |
entity_id | string | null | ID of the affected entity. |
action | string | Action performed. See Actions. |
actor_type | string | Type of actor that performed the action (e.g. user, system, api_key, psp_webhook). |
actor_id | string | null | Actor ID — a user or API key UUID. Null for anonymous or system-initiated events. |
before_state | object | null | State of the entity before the change. Null on creation. |
after_state | object | null | State of the entity after the change. Null on deletion. |
outcome | string | Outcome of the event (PCI DSS 10.3.1): success or failure. |
error_message | string | null | Error message when outcome is failure. Null otherwise. |
ip_address | string | null | Client IP address the request originated from. |
created_at | string | Timestamp of the audit event (ISO 8601 UTC). |
Comparing before_state and after_state tells you exactly what a given event changed — for a connector activation, for example, you would see the old and new status side by side.
Entity types
The entity_type field (and filter) accepts:
organization, merchant, user, auth_session, merchant_connector, routing_profile, routing_rule_node, payment_instrument, order, api_key, user_membership, webhook_config, transaction, transaction_attempts, transaction_refund, transaction_refunds, audit_log.
Actions
The action field (and filter) accepts the following values, grouped here by what they describe:
| Group | Values |
|---|---|
| Entity lifecycle | created, updated, deleted, activated, deactivated, revoked, status_changed |
| Data access | list, read, retrieve |
| Payment operations | create, capture, void, refund |
| Authentication | login_success, login_failure, logout, password_changed, account_locked, account_unlocked, token_issued, token_refreshed, token_revoked |
Endpoints
GET/api/v1/audit-logs
Auth: Organization key (org-wide; optional merchant_id to drill down) or Merchant key (its own logs). Scope: audit_logs:read.
Returns a paginated list of audit log entries, scoped by the authenticated API key. Combine filters to narrow the trail — for example, every failed login in January, or every change ever made to a specific connector.
Query parameters
| Field | Type | Required | Description |
|---|---|---|---|
page | integer | No | Page number, 1-indexed (default 1). |
limit | integer | No | Items per page (default 20, max 100). |
merchant_id | string | No | Drill down to a specific merchant. Organization keys only — ignored for Merchant keys. |
entity_type | string | No | Filter by affected entity type. See Entity types. |
entity_id | string | No | Filter by the affected entity's ID (UUID). |
action | string | No | Filter by action. See Actions. |
actor_type | string | No | Filter by actor type: user, system, scheduler, or psp_webhook. |
actor_id | string | No | Filter by actor ID — a user or API key UUID. |
outcome | string | No | Filter by outcome (PCI DSS 10.3.1): success or failure. |
start_date | string | No | Events on or after this timestamp (ISO 8601, e.g. 2025-01-01T00:00:00.000Z). |
end_date | string | No | Events on or before this timestamp (ISO 8601, e.g. 2025-12-31T23:59:59.999Z). |
Example request
curl -G https://api.tokeflow.com/api/v1/audit-logs \
-H "Authorization: Bearer sk_live_org_…" \
--data-urlencode "merchant_id=mrc_123" \
--data-urlencode "entity_type=merchant_connector" \
--data-urlencode "outcome=success" \
--data-urlencode "start_date=2026-01-01T00:00:00.000Z" \
--data-urlencode "page=1" \
--data-urlencode "limit=20"Example response — 200 OK
The endpoint returns the matching entries in data (newest first) and pagination metadata in meta:
{
"data": [
{
"id": "9d3f2c1e-7a45-4b8e-9c12-3f6a8d0e5b21",
"organization_id": "org_123",
"merchant_id": "mrc_123",
"entity_type": "merchant_connector",
"entity_id": "1f7c9a2d-5e83-4b06-a914-c2d7e8f0a634",
"action": "activated",
"actor_type": "user",
"actor_id": "550e8400-e29b-41d4-a716-446655440000",
"before_state": { "status": "inactive" },
"after_state": { "status": "active" },
"outcome": "success",
"error_message": null,
"ip_address": "203.0.113.42",
"created_at": "2026-01-15T12:30:00.000Z"
},
{
"id": "4b8a1d6f-2c93-47e5-b120-9e5f7a3c8d16",
"organization_id": "org_123",
"merchant_id": "mrc_123",
"entity_type": "merchant_connector",
"entity_id": "1f7c9a2d-5e83-4b06-a914-c2d7e8f0a634",
"action": "updated",
"actor_type": "system",
"actor_id": null,
"before_state": { "priority": 2 },
"after_state": { "priority": 1 },
"outcome": "success",
"error_message": null,
"ip_address": null,
"created_at": "2026-01-14T09:12:44.000Z"
}
],
"meta": {
"page": 1,
"limit": 20,
"total": 87,
"total_pages": 5,
"has_next": true,
"has_prev": false
}
}Failed events are recorded too. A login_failure entry, for example, carries outcome: "failure" and a human-readable error_message, with the source ip_address — useful for spotting brute-force attempts against dashboard accounts.
Errors
Every error uses the standard envelope. The most common cases for this resource:
| HTTP | type | Typical cause |
|---|---|---|
400 | validation_error | Invalid filter value — e.g. an unknown entity_type or a malformed date. |
401 | authentication_error | Missing or invalid API key. |
403 | authorization_error | Key lacks the required scope. |
429 | rate_limit_error | Rate limit exceeded — back off exponentially. |
See Errors for the full envelope and type catalog.
Related
- Pagination and filtering — list conventions used across the API.
- Errors — the standard error envelope.
- Authentication — provision keys and scopes.
- Transactions — the payment events that audit entries reference.