Skip to main content

Audit log

The audit log in the admin tool (Settings → Audit log) records what happens in your organisation: configuration changes, webhook deliveries, GDPR exports, the order-import audit log, and every request your integrations make to the Management API and the Public API.

What is recorded for API requests

Every request that can be tied to your organisation gets one entry, whether it succeeds or fails:
  • Time, method and endpoint, for example GET /v1/management/prescriptions/<prescription_uid>.
  • The requested path. Query parameter names are kept; their values never are.
  • The API key that made the request: its identifier, never its secret.
  • Outcome and status code. For a failed request, the error response your integration received (up to 2,000 characters).
  • Client IP address, user agent and duration.
  • An execution ID that RxScale support can use to find the request in our logs.
Each API entry has one of these events:

Failed attempts

Two kinds of rejected requests are recorded as API authentication failed:
  • A request with the identifier of one of your API keys but the wrong secret (401).
  • A request with a valid API key that lacks the required permission (403).
A request with a missing, malformed or unknown API key cannot be tied to an organisation, so it does not appear in your audit log. A request rejected by rate limiting (429) is not recorded either.
Anyone who knows one of your API key identifiers can cause failed-attempt entries. Repeated failed attempts for a key usually mean an integration has the wrong secret, or that someone is trying to guess it. If in doubt, replace the key.

Order-import audit log

The order-import audit log records every order that reaches RxScale through Public Receiver V2 or the Shopify webhook. Each fulfillment gets one entry, whether the order was imported or refused. A Shopify order with two fulfillments produces two entries. In the admin tool, open Settings → Audit log and set Type to Order import. The Source column shows Public Receiver or Shopify webhook. The Event column shows Order import. Each entry has one of three outcomes. The value is stored as success, success_with_warnings, or rejected. Opening the entry shows that outcome under Outcome of the import, with the label from the table below. The Outcome column of the list shows Success for success and success_with_warnings, and Failed for rejected. When the import was refused or imported with warnings, the Details column shows a short message: each reason is a code and a sentence, for example items_missing: 2 skus not in catalogue. A clean import (success) leaves Details empty. Open the entry to read the shop, the order and fulfillment ids from the source system, the reason codes, and an execution ID our support can use to find the import in our logs. The most common rejection is a prescription-only product on an order with no anamnesis and no prescription, where skip-validation is not set. The order is not created; correcting the order and letting the webhook fire again produces a new entry.
Most rejected imports are retried when the source system sends the order again, and each attempt is its own entry — so several rejected entries for the same order mean the same order kept arriving in the same state, not that several different orders failed. The one exception is an order your shop has already marked fulfilled: we record that rejection once and then ignore repeat deliveries of the same version of it.

What is not recorded as an order import

  • An order your Shopify shop has not marked as paid.
  • An order carrying the rxscale_ignore_order or _rxscale_ignore_order attribute set to true.
  • A delivery for an API key we do not recognise. It cannot be tied to your organisation.
  • A Shopify webhook for a shop we do not know. Public Receiver V2 is different: a request made with one of your API keys that names a shop outside your organisation is recorded, as a rejected import.
  • A repeat delivery of an order we have already imported at that version.
  • A cancellation. Those are not imports.

What is never recorded

  • Request bodies.
  • Query parameter values. Search terms can contain patient data.
  • Response bodies of successful requests.
  • API key secrets.
  • Credentials in a request path, such as a waiting room queue ID. They are replaced by [REDACTED].
  • Order payloads. An order-import entry carries ids, reason codes and a message — never the order body, a customer’s contact details or address, a line item’s title or custom properties, or anamnesis content.

Retention

Configuration changes, webhook deliveries and GDPR exports are kept as before.

Timing and completeness

Entries usually appear within a few seconds of the request. Recording never makes an API request fail, so in rare cases, such as an infrastructure outage, an entry can be missing.

Filtering

The audit log shows the last 7 days by default. You can filter by type, event, outcome, API key and date range. When more than 10,000 entries match, you can page through the newest 10,000; narrow the filters to reach older ones.

Query the audit log

The same log can be read with a Management API key that has the Audit log read permission (audit_log:read). The Admin Tool and the API read one trail. The API is unavailable while audit logging is turned off for the organisation’s Management API. See Audit log.