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

FieldTypeDescription
idstringAudit log ID (UUID).
organization_idstring | nullOrganization the event belongs to.
merchant_idstring | nullMerchant the event belongs to. Null for organization-level events.
entity_typestringType of entity affected. See Entity types.
entity_idstring | nullID of the affected entity.
actionstringAction performed. See Actions.
actor_typestringType of actor that performed the action (e.g. user, system, api_key, psp_webhook).
actor_idstring | nullActor ID — a user or API key UUID. Null for anonymous or system-initiated events.
before_stateobject | nullState of the entity before the change. Null on creation.
after_stateobject | nullState of the entity after the change. Null on deletion.
outcomestringOutcome of the event (PCI DSS 10.3.1): success or failure.
error_messagestring | nullError message when outcome is failure. Null otherwise.
ip_addressstring | nullClient IP address the request originated from.
created_atstringTimestamp 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:

GroupValues
Entity lifecyclecreated, updated, deleted, activated, deactivated, revoked, status_changed
Data accesslist, read, retrieve
Payment operationscreate, capture, void, refund
Authenticationlogin_success, login_failure, logout, password_changed, account_locked, account_unlocked, token_issued, token_refreshed, token_revoked

Endpoints

GET/api/v1/audit-logs

OrgMerchant

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

FieldTypeRequiredDescription
pageintegerNoPage number, 1-indexed (default 1).
limitintegerNoItems per page (default 20, max 100).
merchant_idstringNoDrill down to a specific merchant. Organization keys only — ignored for Merchant keys.
entity_typestringNoFilter by affected entity type. See Entity types.
entity_idstringNoFilter by the affected entity's ID (UUID).
actionstringNoFilter by action. See Actions.
actor_typestringNoFilter by actor type: user, system, scheduler, or psp_webhook.
actor_idstringNoFilter by actor ID — a user or API key UUID.
outcomestringNoFilter by outcome (PCI DSS 10.3.1): success or failure.
start_datestringNoEvents on or after this timestamp (ISO 8601, e.g. 2025-01-01T00:00:00.000Z).
end_datestringNoEvents 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 response200 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:

HTTPtypeTypical cause
400validation_errorInvalid filter value — e.g. an unknown entity_type or a malformed date.
401authentication_errorMissing or invalid API key.
403authorization_errorKey lacks the required scope.
429rate_limit_errorRate limit exceeded — back off exponentially.

See Errors for the full envelope and type catalog.

On this page