Activity and Audit Log
Every change in Covalent writes a line to the activity feed, and an entry to the audit log. The feed is a readable account of what happened; the audit log is the record, kept in a hash chain. Both are read-only through the API.
Endpoints
Section titled “Endpoints”| Method | Endpoint | Scope | Role permission |
|---|---|---|---|
| GET | /api/v2/activities |
activity:read |
activity:view |
| GET | /api/v2/audit-logs |
audit:read |
audit:view |
Administrators and compliance officers keep both; an analyst's role reads the feed only, so an analyst's key is refused the audit log with 403 INSUFFICIENT_SCOPE even when it asked for audit:read.
How Both Lists Work
Section titled “How Both Lists Work”- They hold the key's environment's entries, newest first: feed lines by when they were created, audit entries by when they were logged.
- They page by cursor:
limitfrom1to200(default50) andcursor, as every list. See Lists and Paging. - They filter by codes and IDs only. There is no text search. An unknown parameter, or a value that is not a well-formed code or ID, is
400 INVALID_QUERY; a well-formed code that no entry carries matches nothing. fromandtotake a day (2026-10-09, from its start in UTC) or an ISO 8601 instant with its offset: at or afterfrom, and beforeto.- A key that may not read suspicion reports (
reports:readandstrs:read) is shown no entry about one: no feed line of typestr, no audit entry onTransactionReportor with astr.action. They are left out of every page, cursor and count, so their absence does not show; asking for them by name answers an empty list. - A role without
pii:viewgets free text, recorded values that are not codes or IDs, IP addresses and user agents as***, andmeta.piiMasked: true. The member who did something is named to everyone.
Activity Feed
Section titled “Activity Feed”curl "$COVALENT_URL/api/v2/activities?type=customer&status=warning,error" \ -H "x-api-key: $COVALENT_API_KEY"| Parameter | Description |
|---|---|
type |
What a line is about: travel_rule, customer, wallet, case, str, compliance, threshold, vasp_conflict, provider, integration, webhook, veriscope, user, settings, security or system. |
status |
success, error, info, warning or pending; several joined with commas match any of them. |
action |
The line's action, such as deactivated. |
entityType, entityId |
What the line is about, such as customer and its ID. |
from, to |
Created at or after, and before. |
limit, cursor |
Paging. |
{ "id": "activity_id", "type": "customer", "action": "deactivated", "status": "success", "title": "Customer Deactivated", "description": "Deactivated customer customer_id", "metadata": { "reasonGiven": true }, "entityType": "customer", "entityId": "customer_id", "userId": "user_id", "user": { "id": "user_id", "name": "Jordan Lee", "email": "jordan@example.com" }, "ipAddress": "203.0.113.7", "userAgent": "curl/8.4.0", "createdAt": "2026-10-09T12:00:00.000Z"}user is null when no member did it (a background job), or the member has left.
Audit Log
Section titled “Audit Log”curl "$COVALENT_URL/api/v2/audit-logs?entity=Customer&action=erased" \ -H "x-api-key: $COVALENT_API_KEY"| Parameter | Description |
|---|---|
action |
The change, such as created, updated, erased or str.downloaded. |
entity |
The kind of record changed: one of the entity names below. |
entityId |
The record's ID. |
userId |
The member who made the change. |
from, to |
Logged at or after, and before. |
limit, cursor |
Paging. |
{ "id": "audit_id", "action": "updated", "entity": "CustomerWallet", "entityId": "wallet_id", "oldValue": { "label": "[text]" }, "newValue": { "label": "[text]" }, "userId": "user_id", "user": { "id": "user_id", "name": "Jordan Lee", "email": "jordan@example.com" }, "ipAddress": "203.0.113.7", "userAgent": "curl/8.4.0", "timestamp": "2026-10-09T12:00:00.000Z"}oldValue and newValue record what changed, mostly as codes: free text and customer details are kept out of the log. A change made with an API key is recorded as its owner's, with the request's IP address and user agent. The chain's own fields (its hashes and sequence) are not returned; the chain is verified where it is kept.
Threshold changes apply to both environments, and are logged in the live environment's audit log.
Entity Names
Section titled “Entity Names”entity is the PascalCase name of the kind of record changed:
| Entity | Records |
|---|---|
TravelRuleTransfer |
Transfers |
Customer |
Customers |
CustomerWallet |
Wallets |
Case |
Cases |
TransactionReport |
Regulatory reports, such as suspicion reports (actions str.…) |
ComplianceRule |
Compliance rules |
Threshold |
Regulatory thresholds |
TravelRuleProvider |
Travel Rule provider settings |
Integration |
Screening integration settings |
WebhookSubscription |
Webhook subscriptions |
ApiKey |
API keys |
User |
Users |
TenantMembership |
Team memberships |
MemberInvitation |
Team invitations |
AppSession |
Dashboard sessions |
LegalHold |
Legal holds |
AssetPolicy |
The asset policy |
CompanyProfile |
The company profile |
VaspConflict |
VASP discovery conflicts |
SetupChecklist |
The setup checklist |
OutboxEntry |
Background work |
AuditChainVerificationRun |
Audit chain verifications |