Skip to content

Audit Log ​

Every setting an operator changes through the Operator API is recorded in the platform audit log. With this API you can view the records of your own operations and revert (restore) an operation to its previous values.

MethodPathPurpose
GET/operator/v1/auditGet audit records
POST/operator/v1/audit/{audit_id}/restoreRevert one operation to its previous values

How audit records are kept ​

  • Every write request (POST, PUT, PATCH, DELETE) except POST /launch returns the audit record ID in the X-Audit-Id: <integer> response header. If your admin screens keep their own operation log, store this ID with it. You use it later to check the status with GET /audit?ids= or to restore the change.
  • A record is stored only when the request succeeds (2xx). Failed requests may also carry an X-Audit-Id header, but no record exists for that ID.
  • Requests that change settings have the before and after values (snapshot) attached to the record. Only records with a snapshot can be reverted.
  • If the request includes an X-Operator-Admin: <admin ID> header (^[A-Za-z0-9_.@-]{1,40}$, not part of the signature), the actor is recorded as operator:<operator code>/<admin ID>. Without it, the actor is operator:<operator code>. This value only labels who performed the action and has nothing to do with permissions.
  • An operator can view and revert only records made under its own operator code. Settings changed by the platform are not visible through this API.

Revertible operations ​

OperationReverting restores
PUT /games/{game_code}/bet-limits, PUT /games/{game_code}/lobbyGame bet limits and lobby display settings
PATCH /tables/{table_id}, POST /tables/{table_id}/close, PUT /tables/{table_id}/{settings, live, timers, rake-rule, card-design, currency}Dedicated table settings (including reopening a closed table)
PUT /settings, PUT /card-designOperator settings
PUT /rake-defaultsRake defaults, and the dedicated tables changed along with them by apply_all / rake_floor
POST /players/{external_id}/logoutOnly the player's block status (block). Disconnected sessions are not revived
PATCH /dealers/{dealer_id}, PUT /dealers/{dealer_id}/photo, DELETE /dealers/{dealer_id}/photoDealer name, role, active status and photo (the PIN is not reverted)
DELETE /private-tables/{private_id}Cancellation of a private table reservation
A restore (audit.restore) itselfCancels the restore — back to the values just before the restore

Create requests (POST /tables, POST /dealers, POST /private-tables), badge issuance and revocation, and lobby banner image uploads are recorded only and cannot be reverted (restorable: false).

GET /operator/v1/audit ​

Retrieves audit records newest first (id descending). There are two ways to query.

Query parameters ​

Method 1 — by ID

ParameterTypeRequiredDescription
idsstringYesComma-separated audit record IDs, up to 500 (e.g. ids=1204,1207). Non-numeric values are skipped

When ids is given, the filter and paging parameters below are ignored, and only your own records among them are returned (has_more is always false).

Method 2 — by filter

ParameterTypeRequiredDescription
actionstringNoPrefix match on the operation name (e.g. table. matches table.settings, table.close …)
targetstringNoExact match on the target (e.g. tbl_…, a dealer ID, an operator code)
restorable1NoOnly records with a snapshot
limitintegerNoPage size. Default 100, maximum 500
pageintegerNoPage number starting from 1 (default 1)

Request example ​

http
GET /operator/v1/audit?action=table.&restorable=1&limit=50&page=1 HTTP/1.1
Host: {API_HOST}
X-Operator: acme
X-Api-Key: ak_live_…
X-Timestamp: 1760839200123
X-Nonce: 8d0f2b4a6c8e0d2f4b6a8c0e
X-Signature: 5c1d…

Response example ​

json
{
  "entries": [
    {
      "id": 1207,
      "admin": "operator:acme/jane",
      "action": "table.settings",
      "target": "tbl_0198c1d2e3f47a5b8c9d0e1f2a3b4c5d",
      "detail": { "currency": "PHP", "active": true, "before": { "…": "…" }, "after": { "…": "…" } },
      "ip": "198.51.100.7",
      "created_at": "2026-10-19T03:40:12.88Z",
      "changes": [
        {
          "kind": "table",
          "key": "0198c1d2-e3f4-7a5b-8c9d-0e1f2a3b4c5d",
          "op": "update",
          "fields": {
            "limits.sb": { "before": 100, "after": 200 },
            "limits.bb": { "before": 200, "after": 400 }
          }
        }
      ],
      "restore_of": null,
      "restored_by": null,
      "restorable": true
    },
    {
      "id": 1204,
      "admin": "operator:acme/jane",
      "action": "operator.watch_limit",
      "target": "acme",
      "detail": { "before": 0, "after": 600 },
      "ip": "198.51.100.7",
      "created_at": "2026-10-19T03:31:02.4Z",
      "changes": [
        { "kind": "operator", "key": "0198a0b1-c2d3-7e4f-8a5b-6c7d8e9f0a1b", "op": "update", "fields": { "watch_limit_sec": { "before": 0, "after": 600 } } }
      ],
      "restore_of": null,
      "restored_by": 1210,
      "restorable": true
    }
  ],
  "has_more": false
}

Response fields ​

FieldTypeDescription
entries[].idint64Audit record ID (= the X-Audit-Id of that request)
entries[].adminstringActor — operator:<code> or operator:<code>/<admin ID>
entries[].actionstringOperation name (see the table below)
entries[].targetstringTarget (table ID, dealer ID, game code, player external_id, operator code, etc.)
entries[].detailobjectOperation details (shape varies by operation, usually before / after)
entries[].ipstring | nullIP of the server that made the request
entries[].created_attimestampTime recorded
entries[].changesarraySummary of changed settings (only when a snapshot exists) — see the table below
entries[].restore_ofint64 | nullIf this record is a restore, the ID of the original record it reverted
entries[].restored_byint64 | nullID of the restore record that reverted this record (null if not reverted)
entries[].restorableboolWhether this record can be reverted
has_moreboolWhether there is a next page (query again with page incremented by 1)

changes[]

FieldDescription
kindKind of the changed target — operator, operator_game, table, dealer, dealer_photo, player, private_reservation
keyInternal key of the target row
opupdate, create or delete
fieldsChanged item → { before, after }. JSON settings are expanded into dot paths for the changed fields only (e.g. config.rake.rake_floor). Values such as passwords are masked, and large values such as photo bytes are shortened

changes and detail are summaries for display. Item names are internal platform storage names and may change, so use action, target and restorable for programmatic decisions.

Operation names (action) ​

ScopeNames
Gamegame.bet_limits, game.lobby
Tabletable.create, table.update, table.close, table.settings, table.currency, table.live, table.timers, table.rake_rule, table.card_design, table.private, table.private_cancel
Operatoroperator.timezone, operator.multi_table, operator.watch_limit, operator.rake_defaults, operator.card_design
Playerplayer.logout
Dealerdealer.create, dealer.update, dealer.badge_issue, dealer.badge_reissue, dealer.badge_revoke, dealer.photo, dealer.photo_delete
Restoreaudit.restore
Otherapi <METHOD> <path pattern> — write requests without a dedicated name (e.g. api PUT /operator/v1/lobby-banners)

If one request changes several settings (e.g. changing the time zone and multi-table play together with PUT /settings), several records may be created. In that case, the snapshot and X-Audit-Id are attached to the first record.

Errors ​

HTTPCodeSituation
500INTERNAL_ERRORTemporary server error

POST /operator/v1/audit/{audit_id}/restore ​

Reverts the operation of one audit record to its previous values. The revert itself is also recorded as a new audit record (audit.restore), and its ID is written to restored_by of the original record. Restoring a restore record cancels the restore.

The change is applied immediately to running tables, the dealer tool and entry settings.

Path and request fields ​

FieldTypeRequiredDescription
audit_idint (path)YesID of the audit record to revert
forcebool (body)NoRevert and overwrite even if the same setting was changed again after that operation. Defaults to false

The body may be omitted (signing an empty body or {} means force: false).

Conflict handling ​

Before reverting, the platform checks that the current values match "the values right after that operation". If someone changed the same setting again afterwards, nothing is changed and 409 RESTORE_CONFLICT is returned with a list of conflicts. In that case, either

  1. revert the later operations first, starting from the most recent, or
  2. to ignore the later changes and overwrite them, send the request again with force: true.

Request example ​

bash
curl -X POST {API_BASE}/operator/v1/audit/1207/restore \
  -H 'Content-Type: application/json; charset=utf-8' \
  -H 'X-Operator: acme' -H 'X-Api-Key: ak_live_…' -H 'X-Operator-Admin: jane' \
  -H 'X-Timestamp: 1760839200123' -H 'X-Nonce: 2f4b6a8c0e2d4f6b8a0c2e4d' -H 'X-Signature: b83a…' \
  -d '{}'

Response example ​

200 OK (the X-Audit-Id response header is also the restore record ID)

json
{
  "ok": true,
  "audit_id": 1211,
  "changes": [
    {
      "kind": "table",
      "key": "0198c1d2-e3f4-7a5b-8c9d-0e1f2a3b4c5d",
      "op": "update",
      "fields": {
        "limits.sb": { "before": 200, "after": 100 },
        "limits.bb": { "before": 400, "after": 200 }
      }
    }
  ]
}
FieldTypeDescription
okboolAlways true
audit_idint64ID of the newly created restore record
changesarraySummary of the settings actually changed by the restore (same shape as changes in the list)

Errors ​

HTTPCodedetailsSituation
404NOT_FOUND—Malformed ID, nonexistent record, or a record belonging to another operator or the platform
403NOT_RESTORABLE—Includes changes of a kind that cannot be reverted with operator permissions
409NOT_RESTORABLE—No snapshot to revert (create requests, badges, etc.), or the restore feature is disabled in this environment
409RESTORE_BLOCKED{ "kind": "table", "key": "…" }Cannot be reverted in the current state — e.g. reverting the currency of a table where players are seated. message contains the reason. Try again after the situation changes
409RESTORE_CONFLICT{ "conflicts": [ { "kind": "table", "key": "…" } ] }The same setting was changed again after that operation — see Conflict handling above
500INTERNAL_ERROR—Server error during the restore

Example RESTORE_CONFLICT response:

json
{
  "error": {
    "code": "RESTORE_CONFLICT",
    "message": "changed again after this action — restore the later changes first, or force",
    "details": { "conflicts": [ { "kind": "table", "key": "0198c1d2-e3f4-7a5b-8c9d-0e1f2a3b4c5d" } ] }
  }
}

Docs v1.0.0 · Operator API v1