Developer CenterGuidesAudit Trail & Compliance

    Audit Trail & Compliance

    Metro 2 automatically logs every change to every record at the field level. This audit trail is essential for regulatory compliance, consumer dispute resolution, and internal quality assurance.

    1. How Audit Logging Works

    Every modification to a credit record is automatically captured with full context. No configuration is required—audit logging is always on.

    What Gets Logged

    • • Field-level changes (old value to new value)
    • • Who made the change (user or API key)
    • • When the change occurred (UTC timestamp)
    • • How the change was made (dashboard, API, import)
    • • Submission events (sent to bureau, accepted, rejected)

    Automatic Tracking

    • • No code or configuration needed
    • • Applies to all record modifications
    • • Cannot be disabled or bypassed
    • • Immutable — log entries cannot be edited or deleted
    • • Retained for the full 24-month reporting period

    2. Accessing Audit History

    Retrieve the complete audit history for any record via the API:

    // Get audit history for a specific record
    GET /api/v1/records/rec_abc123/history
    Authorization: Bearer your_api_key
    
    // Response
    {
      "recordId": "rec_abc123",
      "accountNumber": "ACCT-5678",
      "history": [
        {
          "eventId": "evt_001",
          "timestamp": "2025-03-15T14:30:00Z",
          "action": "record.created",
          "actor": {
            "type": "api_key",
            "id": "key_prod_xyz",
            "name": "Production API Key"
          },
          "source": "api",
          "changes": []
        },
        {
          "eventId": "evt_002",
          "timestamp": "2025-03-15T14:30:01Z",
          "action": "submission.sent",
          "actor": {
            "type": "system",
            "id": "system"
          },
          "source": "scheduler",
          "metadata": {
            "submissionId": "sub_xyz789",
            "bureau": "equifax"
          }
        },
        {
          "eventId": "evt_003",
          "timestamp": "2025-03-20T10:15:00Z",
          "action": "record.updated",
          "actor": {
            "type": "user",
            "id": "user_jane",
            "name": "Jane Smith",
            "email": "jane@company.com"
          },
          "source": "dashboard",
          "changes": [
            {
              "field": "currentBalance",
              "oldValue": 5200,
              "newValue": 4900
            },
            {
              "field": "paymentHistoryProfile",
              "oldValue": "0DDDDDDDDDDDDDDDDDDDDD",
              "newValue": "00DDDDDDDDDDDDDDDDDDDD"
            }
          ]
        }
      ]
    }

    Filtering Options

    // Filter by date range
    GET /api/v1/records/rec_abc123/history?from=2025-01-01&to=2025-03-31
    
    // Filter by action type
    GET /api/v1/records/rec_abc123/history?action=record.updated
    
    // Filter by actor
    GET /api/v1/records/rec_abc123/history?actor=user_jane
    
    // Paginate results
    GET /api/v1/records/rec_abc123/history?limit=50&offset=100

    3. Understanding Field-Level Diffs

    Each audit entry for a record update includes a changes array that shows exactly which fields changed, with their previous and new values:

    // Example: Account status change during bankruptcy
    {
      "eventId": "evt_045",
      "timestamp": "2025-03-01T09:00:00Z",
      "action": "record.updated",
      "actor": {
        "type": "api_key",
        "id": "key_prod_xyz",
        "name": "Production API Key"
      },
      "source": "api",
      "changes": [
        {
          "field": "accountStatus",
          "oldValue": "11",
          "newValue": "13",
          "label": "Account Status: Current → Paid or Closed/Zero Balance"
        },
        {
          "field": "currentBalance",
          "oldValue": 4900,
          "newValue": 0,
          "label": "Current Balance: $4,900 → $0"
        },
        {
          "field": "consumerInformationIndicator",
          "oldValue": "",
          "newValue": "H",
          "label": "CII: (none) → Chapter 13 Discharged/Completed"
        },
        {
          "field": "amountPastDue",
          "oldValue": 150,
          "newValue": 0,
          "label": "Amount Past Due: $150 → $0"
        }
      ]
    }

    The label field provides a human-readable description of each change, translating code values into plain language where applicable.

    4. Redacted Fields

    Sensitive fields are automatically redacted in audit logs to protect consumer data. The system records that a change occurred without exposing the full value:

    // SSN changes are masked in audit logs
    {
      "field": "ssn",
      "oldValue": "***-**-1234",
      "newValue": "***-**-5678",
      "redacted": true
    }
    
    // Date of birth is partially masked
    {
      "field": "dateOfBirth",
      "oldValue": "****-**-22",
      "newValue": "****-**-15",
      "redacted": true
    }

    Automatically Redacted Fields

    • • Social Security Number (SSN)
    • • Date of Birth
    • • Full Account Number (last 4 shown)
    • • Consumer Address (street number masked)
    • • Phone Number (last 4 shown)
    • • Email Address (partially masked)

    5. Exporting Audit History for CFPB Exams

    During a CFPB examination or internal audit, you may need to export the complete audit trail for specific records or date ranges. Metro 2 supports bulk export in multiple formats:

    // Export audit history for a date range
    POST /api/v1/audit/export
    Content-Type: application/json
    Authorization: Bearer your_api_key
    
    {
      "from": "2024-01-01",
      "to": "2025-03-31",
      "format": "csv",
      "includeRecordDetails": true,
      "filters": {
        "accountNumbers": ["ACCT-5678", "ACCT-9012"],
        "actions": ["record.created", "record.updated", "submission.sent"]
      }
    }
    
    // Response
    {
      "exportId": "exp_abc123",
      "status": "processing",
      "estimatedRecords": 4500,
      "format": "csv"
    }
    
    // Download when ready
    GET /api/v1/audit/export/exp_abc123/download
    // Returns CSV file
    
    // Supported formats: csv, json, xlsx

    CSV Export

    Flat format suitable for spreadsheets and simple analysis. Each row represents a single field change.

    JSON Export

    Structured format preserving all nested data. Best for programmatic analysis or importing into other systems.

    XLSX Export

    Excel-compatible format with formatting and multiple sheets. Commonly requested by compliance teams and examiners.

    6. Best Practices for Compliance Documentation

    Use Descriptive API Key Names

    Name your API keys clearly (e.g., "Production Monthly Submission" or "Dispute Resolution System") so audit logs show meaningful actor names instead of opaque identifiers.

    Review Audit Logs Monthly

    Build a monthly review process into your compliance workflow. Check for unusual patterns like bulk edits, unexpected field changes, or modifications by unknown actors.

    Export Before Retention Expiration

    Audit logs are retained for 24 months. If your internal policies require longer retention, export the data regularly and store it in your own archive.

    Document Your Dispute Resolution Process

    When resolving consumer disputes, reference specific audit log entries to demonstrate what data was reported, when it changed, and what corrections were made. This documentation is critical for CFPB exams.

    Use Separate API Keys per System

    Create separate API keys for different systems or workflows that modify records. This makes it clear in the audit trail which system made each change.

    Tip

    Audit logs are retained for the full 24-month reporting period and are available for export at any time. Set a calendar reminder to export older records before they age out if your compliance policy requires longer retention.

    Related Resources

    API Reference

    • • GET /api/v1/records/:id/history — Record audit trail
    • • POST /api/v1/audit/export — Bulk export
    • • GET /api/v1/audit/export/:id/download — Download export