> ## Documentation Index
> Fetch the complete documentation index at: https://docs.compliance.legaltalent.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Usage Metrics

Retrieve usage metrics and statistics for KYC operations. Track checks, validations, errors, and watchlist activity over time.

## Endpoint

```
GET /kyc/usage
```

## Authentication

Requires `usage:read` permission. Include your Bearer token in the Authorization header.

## Query Parameters

<ParamFields>
  <ParamField query="granularity" type="string" description="Time granularity: 'hour', 'day', or 'month' (default: 'day')" />

  <ParamField query="year_month" type="string" description="Month in format 'YYYY-MM' (default: current month) - used for 'hour' and 'day' granularities" />

  <ParamField query="date" type="string" description="Date in format 'YYYY-MM-DD' (required when granularity='hour')" />

  <ParamField query="months" type="integer" description="Number of months to retrieve (1-12, default: 1) - used for 'month' granularity" />

  <ParamField query="cache_bust" type="string" description="Set to 'true', '1', or 'yes' to bypass cache and return fresh data" />

  <ParamField query="legacy" type="string" description="Set to 'true', '1', or 'yes' to return legacy response format for backward compatibility" />
</ParamFields>

## Granularity Options

| Granularity | Description                              | Default Period            |
| ----------- | ---------------------------------------- | ------------------------- |
| `hour`      | 24 hourly data points for a specific day | Requires `date` parameter |
| `day`       | Daily data points for a specific month   | Default, up to 30 days    |
| `month`     | Monthly data points for up to 12 months  | Default: 1 month          |

## Request Example

```bash theme={null}
curl "https://stg.kyc.legaltalent.ai/kyc/usage?granularity=day" \
  -H "Authorization: Bearer YOUR_TOKEN"
```

## Additional Request Examples

### Daily Granularity (Specific Month)

```bash theme={null}
curl "https://stg.kyc.legaltalent.ai/kyc/usage?granularity=day&year_month=2024-10" \
  -H "Authorization: Bearer YOUR_TOKEN"
```

### Hourly Granularity (Specific Day)

```bash theme={null}
curl "https://stg.kyc.legaltalent.ai/kyc/usage?granularity=hour&date=2024-10-27" \
  -H "Authorization: Bearer YOUR_TOKEN"
```

### Monthly Granularity (Last 6 Months)

```bash theme={null}
curl "https://stg.kyc.legaltalent.ai/kyc/usage?granularity=month&months=6" \
  -H "Authorization: Bearer YOUR_TOKEN"
```

### Invalidate Cache

```bash theme={null}
curl "https://stg.kyc.legaltalent.ai/kyc/usage?granularity=day&cache_bust=true" \
  -H "Authorization: Bearer YOUR_TOKEN"
```

### Legacy Format

```bash theme={null}
curl "https://stg.kyc.legaltalent.ai/kyc/usage?legacy=true" \
  -H "Authorization: Bearer YOUR_TOKEN"
```

## Response Format

### Success Response (Daily Granularity)

```json theme={null}
{
  "tenant_id": "tenant123",
  "granularity": "day",
  "period": {
    "year_month": "2024-10"
  },
  "data": [
    {
      "timestamp": "2024-10-01",
      "metrics": {
        "check_count": 150,
        "validation_count": 145,
        "error_count": 5,
        "watchlist_scan_count": 20,
        "watchlist_invocation_count": 500,
        "batch_usage_count": 0,
        "batch_job_count": 0,
        "batch_job_completed_count": 0,
        "batch_job_partial_count": 0,
        "batch_job_failed_count": 0,
        "adverse_media_check_count": 45,
        "adverse_media_success_count": 43,
        "adverse_media_error_count": 2,
        "adverse_media_high_risk_count": 3,
        "adverse_media_medium_risk_count": 8,
        "adverse_media_low_risk_count": 12,
        "adverse_media_clear_count": 20,
        "web_validation_check_count": 30,
        "web_validation_success_count": 28,
        "web_validation_error_count": 2,
        "crypto_check_count": 10,
        "crypto_check_success_count": 9,
        "crypto_check_error_count": 1
      }
    }
  ],
  "summary": {
    "check_count": 4500,
    "validation_count": 4350,
    "error_count": 150,
    "watchlist_scan_count": 600,
    "watchlist_invocation_count": 15000,
    "batch_usage_count": 0,
    "batch_job_count": 0,
    "batch_job_completed_count": 0,
    "batch_job_partial_count": 0,
    "batch_job_failed_count": 0,
    "adverse_media_check_count": 1200,
    "adverse_media_success_count": 1180,
    "adverse_media_error_count": 20,
    "adverse_media_high_risk_count": 45,
    "adverse_media_medium_risk_count": 120,
    "adverse_media_low_risk_count": 300,
    "adverse_media_clear_count": 715,
    "web_validation_check_count": 800,
    "web_validation_success_count": 780,
    "web_validation_error_count": 20,
    "crypto_check_count": 250,
    "crypto_check_success_count": 240,
    "crypto_check_error_count": 10
  }
}
```

### Success Response (Hourly Granularity)

```json theme={null}
{
  "tenant_id": "tenant123",
  "granularity": "hour",
  "period": {
    "date": "2024-10-27"
  },
  "data": [
    {
      "timestamp": "2024-10-27T00:00:00Z",
      "metrics": {
        "check_count": 5,
        "validation_count": 5,
        "error_count": 0,
        "watchlist_scan_count": 0,
        "watchlist_invocation_count": 0,
        "adverse_media_check_count": 2,
        "crypto_check_count": 0,
        "web_validation_check_count": 1
      }
    },
    {
      "timestamp": "2024-10-27T01:00:00Z",
      "metrics": {
        "check_count": 12,
        "validation_count": 12,
        "error_count": 0,
        "watchlist_scan_count": 1,
        "watchlist_invocation_count": 5,
        "adverse_media_check_count": 4,
        "crypto_check_count": 1,
        "web_validation_check_count": 3
      }
    }
  ],
  "summary": {
    "check_count": 250,
    "validation_count": 245,
    "error_count": 5,
    "watchlist_scan_count": 10,
    "watchlist_invocation_count": 250,
    "adverse_media_check_count": 50,
    "crypto_check_count": 15,
    "web_validation_check_count": 40
  }
}
```

<Note>
  Metric fields with zero values are always included in the response for consistent data structure across all time periods.
</Note>

### Success Response (Monthly Granularity)

```json theme={null}
{
  "tenant_id": "tenant123",
  "granularity": "month",
  "period": {
    "months": 6
  },
  "data": [
    {
      "timestamp": "2024-05",
      "metrics": {
        "check_count": 12000,
        "validation_count": 11800,
        "error_count": 200,
        "watchlist_scan_count": 1500,
        "watchlist_invocation_count": 45000,
        "adverse_media_check_count": 800,
        "web_validation_check_count": 500,
        "crypto_check_count": 150
      }
    },
    {
      "timestamp": "2024-06",
      "metrics": {
        "check_count": 15000,
        "validation_count": 14700,
        "error_count": 300,
        "watchlist_scan_count": 1800,
        "watchlist_invocation_count": 54000,
        "adverse_media_check_count": 950,
        "web_validation_check_count": 600,
        "crypto_check_count": 180
      }
    }
  ],
  "summary": {
    "check_count": 90000,
    "validation_count": 88200,
    "error_count": 1800,
    "watchlist_scan_count": 10800,
    "watchlist_invocation_count": 324000,
    "adverse_media_check_count": 5500,
    "web_validation_check_count": 3600,
    "crypto_check_count": 1000
  }
}
```

### Legacy Response Format

When using `legacy=true`, the response follows a simplified format for backward compatibility:

```json theme={null}
{
  "status": "success",
  "result": {
    "month": "202501",
    "tenant_id": "tenant123",
    "total_requests": 4500,
    "total_errors": 150,
    "total_matches": 600,
    "avg_processing_ms": 0,
    "by_list": {}
  }
}
```

<Note>
  The legacy format only returns current month data and a simplified metric set. For detailed metrics and historical data, use the standard response format.
</Note>

## Response Fields

| Field         | Type   | Description                                      |
| ------------- | ------ | ------------------------------------------------ |
| `tenant_id`   | string | Your tenant identifier                           |
| `granularity` | string | Time granularity used                            |
| `period`      | object | Period parameters (year\_month, date, or months) |
| `data`        | array  | Array of timestamped metric objects              |
| `summary`     | object | Aggregated totals across all periods             |

### Metric Fields

Each data point contains:

| Field                        | Type    | Description                                    |
| ---------------------------- | ------- | ---------------------------------------------- |
| `check_count`                | integer | Total KYC list checks performed                |
| `validation_count`           | integer | Successful screening validations               |
| `error_count`                | integer | Failed validations/errors                      |
| `watchlist_scan_count`       | integer | Number of watchlist scans executed             |
| `watchlist_invocation_count` | integer | Total watchlist invocations (subjects × lists) |

#### Batch Processing Metrics

| Field                       | Type    | Description                               |
| --------------------------- | ------- | ----------------------------------------- |
| `batch_usage_count`         | integer | Total batch processing usage              |
| `batch_job_count`           | integer | Number of batch jobs submitted            |
| `batch_job_completed_count` | integer | Batch jobs completed successfully         |
| `batch_job_partial_count`   | integer | Batch jobs completed with partial success |
| `batch_job_failed_count`    | integer | Batch jobs that failed                    |

#### Adverse Media Metrics

| Field                             | Type    | Description                     |
| --------------------------------- | ------- | ------------------------------- |
| `adverse_media_check_count`       | integer | Total adverse media checks      |
| `adverse_media_success_count`     | integer | Successful adverse media checks |
| `adverse_media_error_count`       | integer | Failed adverse media checks     |
| `adverse_media_high_risk_count`   | integer | High risk findings              |
| `adverse_media_medium_risk_count` | integer | Medium risk findings            |
| `adverse_media_low_risk_count`    | integer | Low risk findings               |
| `adverse_media_clear_count`       | integer | Clear (no findings) results     |

#### Web Validation Metrics

| Field                          | Type    | Description                 |
| ------------------------------ | ------- | --------------------------- |
| `web_validation_check_count`   | integer | Total web validation checks |
| `web_validation_success_count` | integer | Successful web validations  |
| `web_validation_error_count`   | integer | Failed web validations      |

#### Crypto Wallet Metrics

| Field                        | Type    | Description                |
| ---------------------------- | ------- | -------------------------- |
| `crypto_check_count`         | integer | Total crypto wallet checks |
| `crypto_check_success_count` | integer | Successful crypto checks   |
| `crypto_check_error_count`   | integer | Failed crypto checks       |

## Usage Examples

### Python Example

```python theme={null}
import requests
from datetime import datetime

token = "YOUR_TOKEN"
base_url = "https://stg.kyc.legaltalent.ai/kyc/usage"

# Get daily metrics for current month
response = requests.get(
    f"{base_url}?granularity=day",
    headers={"Authorization": f"Bearer {token}"}
)

if response.status_code == 200:
    data = response.json()
    print(f"Total checks this month: {data['summary']['check_count']}")
    
    # Plot daily trends
    for day in data['data']:
        print(f"{day['timestamp']}: {day['metrics']['check_count']} checks")
```

### JavaScript Example

```javascript theme={null}
const token = "YOUR_TOKEN";

async function getUsageMetrics() {
  const response = await fetch(
    "https://stg.kyc.legaltalent.ai/kyc/usage?granularity=day",
    {
      headers: {
        "Authorization": `Bearer ${token}`
      }
    }
  );
  
  const data = await response.json();
  
  if (response.ok) {
    // Display summary
    console.log(`Total checks: ${data.summary.check_count}`);
    
    // Chart data points
    const chartData = data.data.map(point => ({
      date: point.timestamp,
      checks: point.metrics.check_count,
      errors: point.metrics.error_count
    }));
    
    // Use with charting library (Chart.js, D3, etc.)
    return chartData;
  } else {
    console.error("Error:", data.error);
  }
}
```

## Error Responses

### 400 Bad Request - Invalid Parameters

```json theme={null}
{
  "error": "Invalid date format. Expected YYYY-MM-DD"
}
```

Common validation errors:

* Invalid date format
* Future dates/months
* Invalid granularity value
* Missing required `date` parameter for `hour` granularity
* `months` out of range (must be 1-12)

### 403 Forbidden - Missing Permission

```json theme={null}
{
  "error": "Permission denied: usage:read required"
}
```

### 403 Forbidden - Missing Tenant

```json theme={null}
{
  "error": "Unauthorized: missing tenant_id"
}
```

## Status Codes

| Code | Description                             |
| ---- | --------------------------------------- |
| 200  | Success                                 |
| 400  | Bad Request - Invalid parameters        |
| 401  | Unauthorized - Missing or invalid token |
| 403  | Forbidden - Insufficient permissions    |
| 500  | Internal Server Error                   |

## Caching

* Responses are cached for 5 minutes
* Use `cache_bust=true` to force fresh data
* Cache headers: `Cache-Control: max-age=300`
* With `cache_bust`: `Cache-Control: no-cache, no-store`

## Data Characteristics

* **Gap Filling**: All periods (even with zero activity) are included for continuous charts
* **Immutability**: Historical data never changes, so responses are cacheable
* **Real-time**: Current day/hour data updates as requests are processed
* **Retention**: Metrics are retained for at least 12 months

## Frontend Integration Tips

The response structure is optimized for graph visualization:

```javascript theme={null}
// Daily granularity - 30 data points
{
  data: [
    { timestamp: "2024-10-01", metrics: {...} },
    { timestamp: "2024-10-02", metrics: {...} },
    // ... continuous, no gaps
  ]
}

// Use with any charting library
const labels = data.data.map(d => d.timestamp);
const checks = data.data.map(d => d.metrics.check_count);
const errors = data.data.map(d => d.metrics.error_count);
```
