Tenant Configuration
curl --request GET \
--url https://api.example.com/kyc/tenants/meimport requests
url = "https://api.example.com/kyc/tenants/me"
response = requests.get(url)
print(response.text)const options = {method: 'GET'};
fetch('https://api.example.com/kyc/tenants/me', 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/tenants/me",
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/tenants/me"
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/tenants/me")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.example.com/kyc/tenants/me")
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_bodyTenant Management
Tenant Configuration
GET
/
kyc
/
tenants
/
me
Tenant Configuration
curl --request GET \
--url https://api.example.com/kyc/tenants/meimport requests
url = "https://api.example.com/kyc/tenants/me"
response = requests.get(url)
print(response.text)const options = {method: 'GET'};
fetch('https://api.example.com/kyc/tenants/me', 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/tenants/me",
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/tenants/me"
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/tenants/me")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.example.com/kyc/tenants/me")
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_bodyManage tenant configuration including notification channels, keywords, industries, risk matrix, website validation settings, billing, and account status. Tenant endpoints allow both self-service management (Self-Service Endpoints (
Administrative Endpoints (
/me endpoints) and administrative management (/{tenant_id} endpoints).
Overview
Tenant management endpoints provide:- Self-Service: Tenants can manage their own configuration via
/meendpoints - Administrative: Admins can manage any tenant via
/{tenant_id}endpoints - Configuration Areas: Notifications, keywords, industries, risk matrix, website config, billing
- Account Status: Credits, subscription, usage tracking, watchlist seats
Endpoints Overview
Self-Service Endpoints (/me)
| Method | Endpoint | Description |
|---|---|---|
GET | /kyc/tenants/me | Get current tenant’s configuration |
PATCH | /kyc/tenants/me/notification-channels | Update notification channels |
GET | /kyc/tenants/me/keywords | Get keywords |
PATCH | /kyc/tenants/me/keywords | Update keywords |
GET | /kyc/tenants/me/industries | Get industries |
PATCH | /kyc/tenants/me/industries | Update industries |
GET | /kyc/tenants/me/risk-matrix | Get risk matrix |
PATCH | /kyc/tenants/me/risk-matrix | Update risk matrix |
GET | /kyc/tenants/me/website-config | Get website validation config |
PATCH | /kyc/tenants/me/website-config | Update website validation config |
GET | /kyc/tenants/me/credits | Get available credits |
GET | /kyc/tenants/me/watchlist-seats | Get watchlist seats info |
GET | /kyc/tenants/me/account-status | Get full account status |
Administrative Endpoints (/{tenant_id})
| Method | Endpoint | Description |
|---|---|---|
POST | /kyc/tenants | Create new tenant (admin only) |
GET | /kyc/tenants/{tenant_id} | Get tenant details |
PUT | /kyc/tenants/{tenant_id} | Update tenant (full update, admin only) |
DELETE | /kyc/tenants/{tenant_id} | Delete tenant (admin only) |
PATCH | /kyc/tenants/{tenant_id}/notification-channels | Update notification channels |
PATCH | /kyc/tenants/{tenant_id}/billing | Update billing configuration |
GET | /kyc/tenants/{tenant_id}/keywords | Get keywords |
PATCH | /kyc/tenants/{tenant_id}/keywords | Update keywords |
GET | /kyc/tenants/{tenant_id}/industries | Get industries |
PATCH | /kyc/tenants/{tenant_id}/industries | Update industries |
GET | /kyc/tenants/{tenant_id}/risk-matrix | Get risk matrix |
PATCH | /kyc/tenants/{tenant_id}/risk-matrix | Update risk matrix |
GET | /kyc/tenants/{tenant_id}/website-config | Get website validation config |
PATCH | /kyc/tenants/{tenant_id}/website-config | Update website validation config |
Authentication
- Self-Service Endpoints: Require appropriate read/update permissions
- Administrative Endpoints: Require
tenant:managepermission - Include your Bearer token in the Authorization header
Get Current Tenant Configuration
Retrieve the current tenant’s full configuration.Endpoint
GET /kyc/tenants/me
Request Example
import requests
response = requests.get(
"https://api.kyc.example.com/kyc/tenants/me",
headers={"Authorization": f"Bearer {token}"}
)
tenant = response.json()
const response = await fetch('https://api.kyc.example.com/kyc/tenants/me', {
headers: { 'Authorization': `Bearer ${token}` }
});
const tenant = await response.json();
Response Format
{
"status": "success",
"data": {
"tenant_id": "tenant123",
"name": "My Company",
"status": "active",
"notification_config": {
"webhook_url": "https://example.com/webhooks/kyc",
"webhook_secret": "****************************a1b2",
"notification_emails": ["alerts@example.com", "admin@example.com"],
"slack_webhook_url": "https://hooks.slack.com/services/...",
"batch_notifications_enabled": true
},
"keywords": [
{ "keyword": "gambling", "enabled": true },
{ "keyword": "crypto", "enabled": false }
],
"industries": [
{ "id": 1, "name": "financial_services", "allowed": true, "flagged": false },
{ "id": 2, "name": "gambling", "allowed": false, "flagged": false },
{ "id": 3, "name": "cryptocurrency", "allowed": true, "flagged": true }
],
"risk_matrix": {
"ssl_weight": 0.15,
"industry_weight": 0.20,
"name_match_weight": 0.15,
"sanction_weight": 0.15,
"adverse_media_weight": 0.10,
"social_links_weight": 0.10,
"tranco_weight": 0.15
},
"website_config": {
"adverse_media_enabled": true,
"sanction_check_enabled": true,
"social_links_validation_enabled": true,
"tranco_rank_enabled": true
},
"created_at": "2024-01-01T00:00:00Z",
"updated_at": "2024-11-22T10:30:00Z"
},
"execution_context": {
"timestamp": "2024-11-22T10:30:00Z"
}
}
Account Status
Get comprehensive account status including subscription, credits, usage, and watchlist seats.Endpoint
GET /kyc/tenants/me/account-status
Request Example
import requests
response = requests.get(
"https://api.kyc.example.com/kyc/tenants/me/account-status",
headers={"Authorization": f"Bearer {token}"}
)
status = response.json()
const response = await fetch('https://api.kyc.example.com/kyc/tenants/me/account-status', {
headers: { 'Authorization': `Bearer ${token}` }
});
const status = await response.json();
Response Format
{
"status": "success",
"data": {
"tenant_id": "tenant123",
"tenant_name": "My Company",
"status": "active",
"subscription": {
"status": "active",
"product_id": "prod_enterprise",
"current_period_start": "2024-11-01T00:00:00Z",
"current_period_end": "2024-12-01T00:00:00Z",
"limits": {
"kyc_checks": 1000,
"adverse_media_checks": 500,
"crypto_checks": 200,
"web_validations": 500
},
"usage": {
"kyc_checks": 150,
"adverse_media_checks": 45,
"crypto_checks": 20,
"web_validations": 75
},
"remaining": {
"kyc_checks": 850,
"adverse_media_checks": 455,
"crypto_checks": 180,
"web_validations": 425
}
},
"free_tier": {
"credits": {
"kyc_checks": 10,
"adverse_media_checks": 5,
"crypto_checks": 5,
"web_validations": 10
}
},
"watchlist": {
"available_seats": 100,
"active_subjects": 45
},
"requires_payment": false,
"can_do_screening": true
}
}
Response Fields
| Field | Type | Description |
|---|---|---|
subscription.status | string | none, active, past_due, cancelled |
subscription.limits | object | Monthly limits from subscription plan |
subscription.usage | object | Current month’s usage |
subscription.remaining | object | Remaining quota for current period |
free_tier.credits | object | One-time credits (not renewed monthly) |
watchlist.available_seats | integer | Total watchlist monitoring seats |
watchlist.active_subjects | integer | Currently monitored subjects |
requires_payment | boolean | True if no active subscription and no credits |
can_do_screening | boolean | True if can perform screenings |
Credits
Get available one-time credits (separate from subscription).Endpoint
GET /kyc/tenants/me/credits
Response Format
{
"status": "success",
"data": {
"credits": {
"kyc_checks": 10,
"adverse_media_checks": 5,
"crypto_checks": 5,
"web_validations": 10
}
}
}
Watchlist Seats
Get watchlist monitoring seats information.Endpoint
GET /kyc/tenants/me/watchlist-seats
Response Format
{
"status": "success",
"data": {
"watchlist_seats": {
"available_seats": 100,
"active_subjects": 45,
"remaining_seats": 55,
"default_duration_days": 365
}
}
}
Notification Channels
Update notification channels for alerts and webhooks.Endpoint
PATCH /kyc/tenants/me/notification-channels
Request Body Parameters
Request Example
import requests
response = requests.patch(
"https://api.kyc.example.com/kyc/tenants/me/notification-channels",
headers={
"Authorization": f"Bearer {token}",
"Content-Type": "application/json"
},
json={
"webhook_url": "https://example.com/webhooks/kyc",
"notification_emails": ["alerts@example.com", "admin@example.com"],
"slack_webhook_url": "https://hooks.slack.com/services/T00/B00/XXX",
"batch_notifications_enabled": True
}
)
const response = await fetch('https://api.kyc.example.com/kyc/tenants/me/notification-channels', {
method: 'PATCH',
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
webhook_url: 'https://example.com/webhooks/kyc',
notification_emails: ['alerts@example.com', 'admin@example.com'],
slack_webhook_url: 'https://hooks.slack.com/services/T00/B00/XXX',
batch_notifications_enabled: true
})
});
When setting
webhook_url for the first time, a webhook_secret is automatically generated if not provided. The secret follows the format whsec_ + 64 hex characters.Risk Matrix Configuration
Configure weights for web validation reliability score calculation.Get Risk Matrix
GET /kyc/tenants/me/risk-matrix
Update Risk Matrix
PATCH /kyc/tenants/me/risk-matrix
Request Body Parameters
Important: The sum of all provided weights must equal exactly 1.0. Only include weights for checks you want to enable.
Request Example
import requests
# Basic risk matrix (SSL + Industry only)
response = requests.patch(
"https://api.kyc.example.com/kyc/tenants/me/risk-matrix",
headers={
"Authorization": f"Bearer {token}",
"Content-Type": "application/json"
},
json={
"risk_matrix": {
"ssl_weight": 0.30,
"industry_weight": 0.70
}
}
)
# Advanced risk matrix with all checks
response = requests.patch(
"https://api.kyc.example.com/kyc/tenants/me/risk-matrix",
headers={
"Authorization": f"Bearer {token}",
"Content-Type": "application/json"
},
json={
"risk_matrix": {
"ssl_weight": 0.10,
"industry_weight": 0.15,
"name_match_weight": 0.10,
"sanction_weight": 0.15,
"adverse_media_weight": 0.15,
"social_links_weight": 0.10,
"tranco_weight": 0.10,
"terms_weight": 0.05,
"aml_weight": 0.10
}
}
)
// Basic risk matrix
const response = await fetch('https://api.kyc.example.com/kyc/tenants/me/risk-matrix', {
method: 'PATCH',
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
risk_matrix: {
ssl_weight: 0.30,
industry_weight: 0.70
}
})
});
Response Format
{
"status": "success",
"data": {
"risk_matrix": {
"ssl_weight": 0.10,
"industry_weight": 0.15,
"name_match_weight": 0.10,
"sanction_weight": 0.15,
"adverse_media_weight": 0.15,
"social_links_weight": 0.10,
"tranco_weight": 0.10,
"terms_weight": 0.05,
"aml_weight": 0.10
}
}
}
Website Validation Config
Configure default settings for web validation checks.Get Website Config
GET /kyc/tenants/me/website-config
Update Website Config
PATCH /kyc/tenants/me/website-config
Request Body Parameters
Request Example
import requests
response = requests.patch(
"https://api.kyc.example.com/kyc/tenants/me/website-config",
headers={
"Authorization": f"Bearer {token}",
"Content-Type": "application/json"
},
json={
"website_config": {
"adverse_media_enabled": True,
"sanction_check_enabled": True,
"social_links_validation_enabled": True,
"tranco_rank_enabled": True
}
}
)
const response = await fetch('https://api.kyc.example.com/kyc/tenants/me/website-config', {
method: 'PATCH',
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
website_config: {
adverse_media_enabled: true,
sanction_check_enabled: true,
social_links_validation_enabled: true,
tranco_rank_enabled: true
}
})
});
These settings define the default behavior for web validations. Individual requests can override these defaults using request parameters.
Keywords Management
Keywords are used for website content blacklist filtering during web validation.Get Keywords
GET /kyc/tenants/me/keywords
Update Keywords
PATCH /kyc/tenants/me/keywords
Request Body Parameters
Request Example
import requests
response = requests.patch(
"https://api.kyc.example.com/kyc/tenants/me/keywords",
headers={
"Authorization": f"Bearer {token}",
"Content-Type": "application/json"
},
json={
"keywords": [
{"keyword": "gambling", "enabled": True},
{"keyword": "casino", "enabled": True},
{"keyword": "betting", "enabled": True},
{"keyword": "crypto", "enabled": False}
]
}
)
const response = await fetch('https://api.kyc.example.com/kyc/tenants/me/keywords', {
method: 'PATCH',
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
keywords: [
{ keyword: 'gambling', enabled: true },
{ keyword: 'casino', enabled: true },
{ keyword: 'betting', enabled: true },
{ keyword: 'crypto', enabled: false }
]
})
});
Industries Management
Industries define which business categories are allowed or blocked for the tenant.Get Industries
GET /kyc/tenants/me/industries
Update Industries
PATCH /kyc/tenants/me/industries
Request Body Parameters
Keep IDs stable across updates. This endpoint replaces the complete
industry list. First read the current list with
GET /kyc/tenants/me/industries, then include the id of every existing
industry in the PATCH. If an item is sent without an id, LegalTalent
assigns a new one. IDs belong to the tenant’s catalog and must not be inferred
from array order.Request Example
import requests
response = requests.patch(
"https://api.kyc.example.com/kyc/tenants/me/industries",
headers={
"Authorization": f"Bearer {token}",
"Content-Type": "application/json"
},
json={
"industries": [
{
"id": 101,
"name": "financial_services",
"allowed": True,
"description_en": "Financial Services"
},
{
"id": 102,
"name": "gambling",
"allowed": False,
"description_en": "Gambling & Betting"
},
{
"id": 103,
"name": "cryptocurrency",
"allowed": True,
"flagged": True,
"description_en": "Cryptocurrency & Blockchain"
}
]
}
)
const response = await fetch('https://api.kyc.example.com/kyc/tenants/me/industries', {
method: 'PATCH',
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
industries: [
{ id: 101, name: 'financial_services', allowed: true, description_en: 'Financial Services' },
{ id: 102, name: 'gambling', allowed: false, description_en: 'Gambling & Betting' },
{ id: 103, name: 'cryptocurrency', allowed: true, flagged: true, description_en: 'Cryptocurrency & Blockchain' }
]
})
});
Create Tenant (Admin Only)
Create a new tenant with full configuration.Endpoint
POST /kyc/tenants
Request Body Parameters
Request Example
import requests
response = requests.post(
"https://api.kyc.example.com/kyc/tenants",
headers={
"Authorization": f"Bearer {admin_token}",
"Content-Type": "application/json"
},
json={
"tenant_id": "new-tenant-123",
"name": "New Company Inc.",
"status": "active",
"notification_config": {
"notification_emails": ["admin@newcompany.com"]
},
"risk_matrix": {
"ssl_weight": 0.30,
"industry_weight": 0.70
},
"website_config": {
"adverse_media_enabled": False,
"sanction_check_enabled": True
},
"billing_config": {
"plan_type": "MONTHLY",
"contracted_limits": {
"kyc_checks": 100,
"adverse_media_checks": 50
},
"credits": {
"kyc_checks": 10,
"adverse_media_checks": 5
}
}
}
)
const response = await fetch('https://api.kyc.example.com/kyc/tenants', {
method: 'POST',
headers: {
'Authorization': `Bearer ${adminToken}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
tenant_id: 'new-tenant-123',
name: 'New Company Inc.',
status: 'active',
notification_config: {
notification_emails: ['admin@newcompany.com']
},
billing_config: {
plan_type: 'MONTHLY',
credits: { kyc_checks: 10 }
}
})
});
Update Billing Configuration (Admin Only)
Update billing settings for a tenant.Endpoint
PATCH /kyc/tenants/{tenant_id}/billing
Request Body Parameters
Request Example
import requests
response = requests.patch(
f"https://api.kyc.example.com/kyc/tenants/{tenant_id}/billing",
headers={
"Authorization": f"Bearer {admin_token}",
"Content-Type": "application/json"
},
json={
"plan_type": "MONTHLY",
"contracted_limits": {
"kyc_checks": 1000,
"adverse_media_checks": 500
},
"usage_alerts": {
"enabled": True,
"thresholds": [75, 90, 95]
},
"watchlist_config": {
"available_seats": 100,
"default_duration_days": 365
},
"credits": {
"kyc_checks": 50,
"adverse_media_checks": 25
}
}
)
Delete Tenant (Admin Only)
Soft-delete (deactivate) a tenant.Endpoint
DELETE /kyc/tenants/{tenant_id}
Request Example
curl -X DELETE https://api.kyc.example.com/kyc/tenants/tenant123 \
-H "Authorization: Bearer YOUR_ADMIN_TOKEN"
Response Format
{
"status": "success",
"data": {
"message": "Tenant tenant123 deactivated successfully"
}
}
Permissions Reference
| Permission | Description |
|---|---|
tenant:manage | Full admin access to all tenant endpoints |
tenant:read | Read own tenant configuration |
notification-channels:read | Read notification settings |
notification-channels:update | Update notification settings |
keywords:read | Read keywords |
keywords:update | Update keywords |
industries:read | Read industries |
industries:update | Update industries |
risk-matrix:read | Read risk matrix |
risk-matrix:update | Update risk matrix |
website-config:read | Read website config |
website-config:update | Update website config |
billing:read | Read billing information |
billing:update | Update billing configuration |
Status Codes
| Code | Description |
|---|---|
| 200 | Success |
| 201 | Created - Tenant created successfully |
| 400 | Bad Request - Invalid parameters or validation error |
| 401 | Unauthorized - Missing or invalid token |
| 403 | Forbidden - Insufficient permissions |
| 404 | Not Found - Tenant not found |
| 409 | Conflict - Tenant already exists |
| 500 | Internal Server Error |
Best Practices
Use Account Status
Use
/me/account-status for dashboard displays - it provides all relevant information in a single call.Risk Matrix Design
Design your risk matrix weights to sum exactly to 1.0. Only include weights for checks you actually use.
Webhook Security
Always verify webhook signatures using your
webhook_secret. It’s auto-generated for security.List Replacement
Keywords and industries are fully replaced on update. Include all items when updating.
Integration Tips
- Configuration Hierarchy: Website config sets defaults → Request parameters override defaults
- Credit Priority: Free tier credits are used after subscription quota is exhausted
- Watchlist Seats: Track
remaining_seatsto prevent over-enrollment - Risk Matrix: Weights dynamically adjust based on which checks are enabled in the request
- Audit Trail:
created_byandupdated_byfields track who made changes