{"title":"Audit Event - Liquid Tag Reference","slug":"audit-event-tag-reference","url":"https://support.storeconnect.com/articles/audit-event-tag-reference","url_markdown":"https://support.storeconnect.com/articles/audit-event-tag-reference.md","subtitle":null,"summary":"The `audit_event` tag records a custom entry in the audit log from a theme. Use it to capture business-significant actions that are not standard StoreConnect events, with an optional message and structured detail.","type":"Developer_Documentation","video_url":"","keywords":"liquid, tags, audit_event, audit log, custom events, security, theme, storeconnect","last_modified":"2026-10-07T05:47:34+0000","body_markdown":"The `audit_event` tag records a custom entry in the [audit log](audit-log) from a theme. Use it to capture actions that matter to the business but are not standard StoreConnect events, such as a loyalty tier change or a customer deleting a saved address.\n\n## Syntax\n\n\n```liquid\n\n{% audit_event \"loyalty_tier_changed\" %}\n\n{% audit_event \"loyalty_tier_changed\", message: \"Upgraded to gold\" %}\n\n{%- assign tier_detail = '{\"from\":\"silver\",\"to\":\"gold\"}' | deserialize -%}\n{% audit_event \"loyalty_tier_changed\",\n   message: \"Upgraded to gold\",\n   detail: tier_detail %}\n```\n\n\n| Property | Value |\n|----------|-------|\n| **Tag Name** | `audit_event` |\n| **Type** | Simple tag |\n| **Output** | None. The tag renders an empty string |\n| **POS support** | No |\n\n## Parameters\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| First argument | String | Yes | The name of your event, in quotes. Recorded in **Custom Event Name** |\n| `message` | String | No | A short human-readable summary, up to 255 characters |\n| `detail` | Object | No | Event-specific detail, stored as JSON in **Details**. Build it with `deserialize` |\n\n## Building the detail value\n\nLiquid has no object literal, so build `detail` with the [`deserialize`](deserialize-filter-reference) filter and pass the resulting object:\n\n\n```liquid\n\n{%- assign deleted_detail = '{\"nickname\":\"Office\"}' | deserialize -%}\n{% audit_event \"address_book_entry_deleted\",\n   message: \"Customer deleted a saved address\",\n   detail: deleted_detail %}\n```\n\n\n:::warning\nPassing a raw JSON string rather than a deserialized object stores it as an escaped string instead of structured detail, and secret filtering cannot apply to it. Secret filtering matches on key names, so it needs real keys to match against.\n:::\n\n## Recorded values\n\nEvery entry the tag makes is recorded on the [Audit Log](audit-log-object-reference) object as:\n\n| Field | Value |\n|-------|-------|\n| **Event Type** | `custom`, always |\n| **Custom Event Name** | Your first argument |\n| **Category** | `CUSTOM` |\n| **Severity** | `NOTICE` |\n| **Channel** | `web` |\n| **Outcome** | `success` |\n| **Actor** | The logged-in customer, when there is one |\n\n**Event Type** is always `custom`, so a theme cannot record an entry that looks like a standard event such as `login` or `payment_succeeded`.\n\n## Limits\n\n- **The store must record the Custom category.** Because entries are `NOTICE`, they are recorded only when the store's **Audit Log Level** is `Standard` or `Verbose` and `Custom` is one of its **Audit Log Categories**. Categories are all enabled when **Audit Log Categories** is blank.\n- **Ten entries per request.** Further calls in the same request are ignored silently. Do not put this tag inside a loop over products or line items.\n- **Secrets are stripped by key name.** Any key in a structured `detail` whose name contains `password`, `passwd`, `secret`, `token`, `api_key`, `apikey`, `_key`, `crypt`, `salt`, `certificate`, `card_number`, `cardnumber`, `authorization`, `ssn`, or `otp`, or is exactly `pan`, `pin`, `cvv`, or `cvn`, is stored as `[FILTERED]`. A key that names a secret any other way, such as `social_security_number` or a bare `key`, is stored as written. Filtering matches key names, so it cannot redact a secret buried in a plain string. Do not rely on it, and avoid passing sensitive values at all.\n- **Length limits.** `message` is capped at 255 characters and `detail` at 32768. Longer values are truncated rather than rejected, so a `detail` over the limit is stored as incomplete JSON.\n- **A failed write never breaks the page.** If the entry cannot be recorded, the tag renders nothing and the page continues. An undefined variable passed as `message` or `detail` still shows a Liquid error, because it is evaluated before the entry is written.\n\n## Example\n\nRecord a preference change by placing the tag on the page your marketing preferences form returns to after a successful submit, such as `/preferences-saved`. The tag runs each time that page renders, so use a page that only a successful submit leads to.\n\n\n```liquid\n\n{% audit_event \"marketing_preferences_changed\",\n   message: \"Customer updated marketing preferences\" %}\n```\n\n\nThe entry appears on the **Audit Log** list with **Event Type** `custom` and **Custom Event Name** `marketing_preferences_changed`."}