How-to: audit
Server-side audit history from Dynamics 365 — distinct from the local
session audit journal, which records only this CLI's own mutations. See the
CLI reference for every flag.
Prerequisites
- The calling user needs the
prvReadRecordAuditHistoryandprvReadAuditSummaryprivileges. - Auditing must be enabled at the org level, the table level, and (for column-level
detail) the column level in D365. When auditing is off the server returns a
well-formed but empty
AuditDetailCollection— no error, just zero rows.
Retrieve a record's change history
crm --json audit history accounts <record-guid>
Returns an AuditDetailCollection with the paging fields MoreRecords (bool),
PagingCookie (str), and TotalRecordCount (int), plus an AuditDetails array
— one entry per audited change event.
Each AuditDetail entry carries an AuditDetailType field (e.g.
AttributeAuditDetail) derived from the Web API @odata.type discriminator.
The standard emit envelope strips all @odata.* keys (ADR 0008), so without
this promotion the subtype would be invisible — AuditDetailType is the
canonical field to branch on.
Page through a long history
MoreRecords: true means more pages exist. Pass the returned PagingCookie
to fetch the next page:
# Page 1 (default)
crm --json audit history accounts <record-guid> --count 20
# Page 2 — copy the PagingCookie from the page 1 response
crm --json audit history accounts <record-guid> --count 20 \
--paging-cookie '<cookie from prior response>'
The --page option selects a 1-based page number when you know the target
page upfront (no cookie needed). Combine --page with --count to jump
directly to a page of a known size.
Retrieve a single audit row by ID
crm --json audit detail <auditid-guid>
Decodes the AuditDetail for one row in the audits table. The concrete type
is surfaced as AuditDetailType (same promotion as above). Use this to inspect
the full before/after field values for a specific change event when you already
have the auditid from an audit history result.
Why not action function?
RetrieveRecordChangeHistory requires a Target EntityReference and a
PagingInfo complex object passed as OData parameter aliases
(?@target=...&@paginginfo=...). The action function command encodes
parameters inline as Fn(k=v), which cannot express complex-type aliases.
The audit group handles this encoding internally, making these functions
reachable from the CLI for the first time.
Session audit vs server-side audit
crm session audit |
crm audit history |
|
|---|---|---|
| What it records | Mutations issued by this CLI in the current session | All audited changes stored in the D365 server audit log |
| Where data lives | Local JSONL file (~/.crm/audit/<session>.jsonl) |
D365 audits entity, server-side |
| Connection needed | No | Yes |
| Privilege needed | None (local file) | prvReadRecordAuditHistory + prvReadAuditSummary |