Usage Metrics
curl --request GET \
--url https://api.example.com/kyc/usageimport requests
url = "https://api.example.com/kyc/usage"
response = requests.get(url)
print(response.text)const options = {method: 'GET'};
fetch('https://api.example.com/kyc/usage', 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/kyc/usage",
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/kyc/usage"
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/kyc/usage")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.example.com/kyc/usage")
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_bodyReporting & Analytics
Usage Metrics
GET
/
kyc
/
usage
Usage Metrics
curl --request GET \
--url https://api.example.com/kyc/usageimport requests
url = "https://api.example.com/kyc/usage"
response = requests.get(url)
print(response.text)const options = {method: 'GET'};
fetch('https://api.example.com/kyc/usage', 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/kyc/usage",
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/kyc/usage"
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/kyc/usage")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.example.com/kyc/usage")
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_bodyRetrieve usage metrics and statistics for KYC operations. Track checks, validations, errors, and watchlist activity over time.
Common validation errors:
Endpoint
GET /kyc/usage
Authentication
Requiresusage:read permission. Include your Bearer token in the Authorization header.
Query Parameters
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
curl "https://stg.kyc.legaltalent.ai/kyc/usage?granularity=day" \
-H "Authorization: Bearer YOUR_TOKEN"
Additional Request Examples
Daily Granularity (Specific Month)
curl "https://stg.kyc.legaltalent.ai/kyc/usage?granularity=day&year_month=2024-10" \
-H "Authorization: Bearer YOUR_TOKEN"
Hourly Granularity (Specific Day)
curl "https://stg.kyc.legaltalent.ai/kyc/usage?granularity=hour&date=2024-10-27" \
-H "Authorization: Bearer YOUR_TOKEN"
Monthly Granularity (Last 6 Months)
curl "https://stg.kyc.legaltalent.ai/kyc/usage?granularity=month&months=6" \
-H "Authorization: Bearer YOUR_TOKEN"
Invalidate Cache
curl "https://stg.kyc.legaltalent.ai/kyc/usage?granularity=day&cache_bust=true" \
-H "Authorization: Bearer YOUR_TOKEN"
Legacy Format
curl "https://stg.kyc.legaltalent.ai/kyc/usage?legacy=true" \
-H "Authorization: Bearer YOUR_TOKEN"
Response Format
Success Response (Daily Granularity)
{
"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)
{
"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
}
}
Metric fields with zero values are always included in the response for consistent data structure across all time periods.
Success Response (Monthly Granularity)
{
"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 usinglegacy=true, the response follows a simplified format for backward compatibility:
{
"status": "success",
"result": {
"month": "202501",
"tenant_id": "tenant123",
"total_requests": 4500,
"total_errors": 150,
"total_matches": 600,
"avg_processing_ms": 0,
"by_list": {}
}
}
The legacy format only returns current month data and a simplified metric set. For detailed metrics and historical data, use the standard response format.
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
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
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
{
"error": "Invalid date format. Expected YYYY-MM-DD"
}
- Invalid date format
- Future dates/months
- Invalid granularity value
- Missing required
dateparameter forhourgranularity monthsout of range (must be 1-12)
403 Forbidden - Missing Permission
{
"error": "Permission denied: usage:read required"
}
403 Forbidden - Missing Tenant
{
"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=trueto 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:// 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);