Get Consent Audit Trail
curl --request GET \
--url https://api.example.com/v2/consent/user/{userId}/auditimport requests
url = "https://api.example.com/v2/consent/user/{userId}/audit"
response = requests.get(url)
print(response.text)const options = {method: 'GET'};
fetch('https://api.example.com/v2/consent/user/{userId}/audit', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.example.com/v2/consent/user/{userId}/audit",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.example.com/v2/consent/user/{userId}/audit"
req, _ := http.NewRequest("GET", url, nil)
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.example.com/v2/consent/user/{userId}/audit")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.example.com/v2/consent/user/{userId}/audit")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
response = http.request(request)
puts response.read_bodyConsent
Get Consent Audit Trail
Retrieve paginated audit log of all consent changes for a user
GET
/
v2
/
consent
/
user
/
{userId}
/
audit
Get Consent Audit Trail
curl --request GET \
--url https://api.example.com/v2/consent/user/{userId}/auditimport requests
url = "https://api.example.com/v2/consent/user/{userId}/audit"
response = requests.get(url)
print(response.text)const options = {method: 'GET'};
fetch('https://api.example.com/v2/consent/user/{userId}/audit', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.example.com/v2/consent/user/{userId}/audit",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.example.com/v2/consent/user/{userId}/audit"
req, _ := http.NewRequest("GET", url, nil)
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.example.com/v2/consent/user/{userId}/audit")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.example.com/v2/consent/user/{userId}/audit")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
response = http.request(request)
puts response.read_bodyOverview
Retrieves the complete audit trail of all consent changes for a user. Essential for compliance reporting, regulatory audits, and investigating consent history.The audit trail is immutable - all consent changes are permanently recorded with complete before/after snapshots for regulatory compliance.
Endpoint
GET https://api.baanx.com/v2/consent/user/{userId}/audit
Headers
| Header | Required | Description |
|---|---|---|
x-client-key | ✅ | Your public API key |
x-us-env | ❌ | Set to true for US region routing |
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
userId | string | ✅ | User identifier to retrieve audit trail for |
Query Parameters
| Parameter | Type | Required | Description | Default |
|---|---|---|---|---|
limit | integer | ❌ | Number of records per page (max 100) | 50 |
offset | integer | ❌ | Starting position for pagination | 0 |
Response
{
"userId": "user_123abc456def",
"auditRecords": [
{
"auditId": "audit_001",
"action": "created",
"timestamp": "2024-01-15T10:30:00Z",
"consentSetId": "550e8400-e29b-41d4-a716-446655440001",
"changes": {
"before": null,
"after": {
"consentType": "termsAndPrivacy",
"consentStatus": "granted"
}
},
"metadata": {
"ipAddress": "192.168.1.1",
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 14_0 like Mac OS X)",
"timestamp": "2024-01-15T10:30:00Z",
"clientId": "mobile-app-ios-v2.1.0"
}
},
{
"auditId": "audit_002",
"action": "created",
"timestamp": "2024-01-15T10:30:00Z",
"consentSetId": "550e8400-e29b-41d4-a716-446655440001",
"changes": {
"before": null,
"after": {
"consentType": "marketingNotifications",
"consentStatus": "granted"
}
},
"metadata": {
"ipAddress": "192.168.1.1",
"userAgent": "Mozilla/5.0...",
"timestamp": "2024-01-15T10:30:00Z"
}
},
{
"auditId": "audit_003",
"action": "revoked",
"timestamp": "2024-01-20T14:22:00Z",
"consentSetId": "550e8400-e29b-41d4-a716-446655440001",
"changes": {
"before": {
"consentType": "marketingNotifications",
"consentStatus": "granted"
},
"after": {
"consentType": "marketingNotifications",
"consentStatus": "revoked"
}
},
"metadata": {
"ipAddress": "192.168.1.10",
"userAgent": "Mozilla/5.0...",
"timestamp": "2024-01-20T14:22:00Z"
}
}
],
"pagination": {
"total": 3,
"limit": 50,
"offset": 0
},
"_links": {
"self": {
"href": "https://api.baanx.com/v2/consent/user/user_123abc456def/audit?limit=50&offset=0",
"method": "GET"
},
"next": null,
"prev": null
}
}
Audit Record Structure
| Field | Type | Description |
|---|---|---|
auditId | string | Unique identifier for this audit record |
action | string | Action type: created, updated, revoked |
timestamp | string (ISO 8601) | When the change occurred |
consentSetId | string (UUID) | Consent set containing this change |
changes.before | object|null | State before change (null for creation) |
changes.after | object | State after change |
metadata | object | Additional context (IP, user agent, etc.) |
Action Types
| Action | Description | Before State | After State |
|---|---|---|---|
created | Initial consent creation | null | Consent record |
updated | Consent status changed | Original status | New status |
revoked | Consent was revoked | granted status | revoked status |
Pagination
Uselimit and offset to paginate through large audit trails:
async function getAllAuditRecords(userId: string) {
let allRecords = [];
let offset = 0;
const limit = 100;
while (true) {
const response = await fetch(
`https://api.baanx.com/v2/consent/user/${userId}/audit?limit=${limit}&offset=${offset}`,
{
headers: {
'x-client-key': process.env.BAANX_CLIENT_KEY!
}
}
);
const { auditRecords, pagination } = await response.json();
allRecords.push(...auditRecords);
if (offset + limit >= pagination.total) break;
offset += limit;
}
return allRecords;
}
Code Examples
TypeScript - Basic Audit Retrieval
async function getConsentAudit(
userId: string,
limit: number = 50,
offset: number = 0
) {
const response = await fetch(
`https://api.baanx.com/v2/consent/user/${userId}/audit?limit=${limit}&offset=${offset}`,
{
headers: {
'x-client-key': process.env.BAANX_CLIENT_KEY!
}
}
);
if (!response.ok) {
const error = await response.json();
throw new Error(`Audit retrieval failed: ${error.details.join(', ')}`);
}
return response.json();
}
const audit = await getConsentAudit('user_123abc456def');
console.log(`Total audit records: ${audit.pagination.total}`);
TypeScript - Export for Compliance
async function exportConsentAudit(userId: string) {
const allRecords = await getAllAuditRecords(userId);
const report = {
userId,
exportDate: new Date().toISOString(),
totalChanges: allRecords.length,
records: allRecords.map(record => ({
date: record.timestamp,
action: record.action,
consentType: record.changes.after?.consentType,
oldStatus: record.changes.before?.consentStatus,
newStatus: record.changes.after?.consentStatus,
ipAddress: record.metadata?.ipAddress
}))
};
return report;
}
const complianceReport = await exportConsentAudit('user_123abc456def');
await saveToFile(`audit_${userId}.json`, JSON.stringify(complianceReport, null, 2));
Python
import requests
def get_consent_audit(user_id, limit=50, offset=0):
response = requests.get(
f'https://api.baanx.com/v2/consent/user/{user_id}/audit',
params={'limit': limit, 'offset': offset},
headers={
'x-client-key': os.getenv('BAANX_CLIENT_KEY')
}
)
response.raise_for_status()
return response.json()
audit = get_consent_audit('user_123abc456def')
print(f"Total audit records: {audit['pagination']['total']}")
for record in audit['auditRecords']:
print(f"{record['timestamp']}: {record['action']} - {record['changes']['after'].get('consentType')}")
cURL
curl -X GET "https://api.baanx.com/v2/consent/user/user_123abc456def/audit?limit=50&offset=0" \
-H "x-client-key: your_client_key"
Use Cases
Regulatory Audits
Regulatory Audits
Generate comprehensive audit reports for regulators:
async function generateRegulatoryAudit(userId: string) {
const { auditRecords } = await getConsentAudit(userId, 1000, 0);
return {
userIdentifier: userId,
auditPeriod: {
from: auditRecords[0]?.timestamp,
to: auditRecords[auditRecords.length - 1]?.timestamp
},
totalChanges: auditRecords.length,
consentGranted: auditRecords.filter(
r => r.action === 'created' && r.changes.after.consentStatus === 'granted'
).length,
consentRevoked: auditRecords.filter(r => r.action === 'revoked').length,
detailedRecords: auditRecords
};
}
Data Subject Access Requests (DSAR)
Data Subject Access Requests (DSAR)
Fulfill user requests for their consent history:
async function handleDSAR(userId: string) {
const { auditRecords } = await getConsentAudit(userId);
return {
requestDate: new Date().toISOString(),
userId,
consentHistory: auditRecords.map(record => ({
date: record.timestamp,
action: record.action,
consentType: record.changes.after?.consentType,
status: record.changes.after?.consentStatus,
capturedFrom: {
ipAddress: record.metadata?.ipAddress,
device: record.metadata?.userAgent
}
}))
};
}
Consent Timeline Visualization
Consent Timeline Visualization
Display user’s consent history in UI:
async function getConsentTimeline(userId: string) {
const { auditRecords } = await getConsentAudit(userId);
return auditRecords.map(record => ({
id: record.auditId,
date: new Date(record.timestamp),
action: record.action,
description: formatAuditDescription(record),
icon: getActionIcon(record.action)
}));
}
function formatAuditDescription(record: AuditRecord): string {
const { action, changes } = record;
const type = changes.after?.consentType;
if (action === 'created') {
return `Granted consent for ${type}`;
} else if (action === 'revoked') {
return `Revoked consent for ${type}`;
}
return `Updated ${type}`;
}
Legal Defense
Legal Defense
Prove consent was properly obtained:
async function proveLawfulConsent(userId: string, disputeDate: string) {
const { auditRecords } = await getConsentAudit(userId);
const relevantRecords = auditRecords.filter(
record => new Date(record.timestamp) <= new Date(disputeDate)
);
return {
disputeDate,
consentWasGranted: relevantRecords.some(
r => r.action === 'created' && r.changes.after.consentStatus === 'granted'
),
consentWasRevoked: relevantRecords.some(r => r.action === 'revoked'),
evidenceRecords: relevantRecords,
captureDetails: relevantRecords.map(r => ({
timestamp: r.timestamp,
ipAddress: r.metadata?.ipAddress,
userAgent: r.metadata?.userAgent
}))
};
}
Best Practices
Data Retention: Audit trails should be retained according to regulatory requirements (typically 6-7 years). Never delete audit records even after user account closure.
Performance: For large audit trails, use pagination and process records in batches rather than loading all at once.
Related Endpoints
Get User Consent Status
Check current consent status
Revoke Consent
Create revocation audit records
Compliance Guide
Regulatory compliance best practices
Implementation Guide
Full integration guide
Was this page helpful?
⌘I