Explain Match
Get a detailed breakdown of how a screening match was scored, including algorithm contributions and confidence factors. This endpoint supports compliance audit requirements by providing transparency into matching decisions.
Endpoint: POST /v1/screen/explain
Request​
Headers​
| Header | Required | Description |
|---|---|---|
x-api-key | Yes | Your API key |
Content-Type | Yes | application/json |
Request Body​
| Field | Type | Required | Description |
|---|---|---|---|
| query_name | string | Yes | The name that was searched |
| matched_name | string | Yes | The name that was matched from the sanctions list |
| entity_type | string | No | individual, organization, vessel, aircraft, unknown |
| query_identifiers | object | No | Document numbers from the original query |
| matched_identifiers | array | No | Document numbers from the matched entity |
Example Request​
curl -X POST "https://api.sanctionswise.orchestraprime.ai/v1/screen/explain" \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"query_name": "Viktor Bout",
"matched_name": "BOUT, Viktor",
"entity_type": "individual"
}'
Response​
Success Response​
{
"query": {
"original": "Viktor Bout",
"normalized": "VIKTOR BOUT",
"tokens": ["VIKTOR", "BOUT"]
},
"matched": {
"original": "BOUT, Viktor",
"normalized": "BOUT VIKTOR",
"tokens": ["BOUT", "VIKTOR"]
},
"scoring_breakdown": {
"jaro_winkler": 0.3200,
"sequence_matcher": 0.2550,
"phonetic": 0.3000,
"total": 0.8750
},
"algorithm_details": {
"exact_match": {
"matched": false,
"score": 0.0,
"description": "Direct comparison of normalized names"
},
"jaro_winkler": {
"score": 0.8000,
"weight": 0.40,
"weighted_contribution": 0.3200,
"details": {
"string1_length": 11,
"string2_length": 11,
"match_window": 4,
"matching_characters": 11,
"transpositions": 4,
"common_prefix_length": 0,
"jaro_similarity": 0.7879,
"winkler_adjustment": 0.0
},
"description": "Measures similarity with emphasis on common prefix"
},
"sequence_matcher": {
"score": 0.8500,
"weight": 0.30,
"weighted_contribution": 0.2550,
"matching_blocks": [
{"query_start": 0, "match_start": 5, "length": 6},
{"query_start": 7, "match_start": 0, "length": 4}
],
"longest_match_length": 6,
"description": "Longest common subsequence based similarity"
},
"phonetic": {
"score": 1.0000,
"weight": 0.30,
"weighted_contribution": 0.3000,
"details": {
"query_soundex_codes": [
{"word": "VIKTOR", "code": "V236"},
{"word": "BOUT", "code": "B300"}
],
"matched_soundex_codes": [
{"word": "BOUT", "code": "B300"},
{"word": "VIKTOR", "code": "V236"}
],
"soundex_matches": ["V236", "B300"],
"query_metaphone_codes": [
{"word": "VIKTOR", "primary": "FKTR", "alternate": "FKTR"},
{"word": "BOUT", "primary": "PT", "alternate": "PT"}
],
"matched_metaphone_codes": [
{"word": "BOUT", "primary": "PT", "alternate": "PT"},
{"word": "VIKTOR", "primary": "FKTR", "alternate": "FKTR"}
],
"metaphone_matches": ["FKTR", "PT"]
},
"description": "Soundex and Double Metaphone phonetic comparison"
}
},
"final_score": 0.9188,
"match_classification": "confident",
"confidence_factors": [
"Entity type match bonus applied (+5%)",
"Score indicates confident match",
"Names contain same tokens in different order",
"Soundex codes match: V236, B300",
"Metaphone codes match: FKTR, PT"
],
"timestamp": "2026-01-26T19:30:00.000000Z"
}
Response Fields​
| Field | Type | Description |
|---|---|---|
| query | object | Original and normalized query name with tokens |
| matched | object | Original and normalized matched name with tokens |
| scoring_breakdown | object | Weighted score contribution from each algorithm |
| algorithm_details | object | Detailed breakdown of each matching algorithm |
| final_score | number | Combined confidence score (0.0-1.0) |
| match_classification | string | Human-readable match category |
| confidence_factors | array | Explanations for scoring decisions |
| timestamp | string | ISO 8601 timestamp |
Match Classifications​
| Classification | Score Range | Description |
|---|---|---|
exact | 1.0 | Normalized names are identical |
high_confidence | 0.95+ | Very high likelihood of true match |
confident | 0.85-0.94 | Confident match |
potential | 0.70-0.84 | Potential match - manual review recommended |
weak | Below 0.70 | Below typical matching threshold |
Algorithm Weights​
The final score is calculated using these weights:
| Algorithm | Weight | Description |
|---|---|---|
| Jaro-Winkler | 40% | Character-level similarity with prefix bonus |
| Sequence Matcher | 30% | Longest common subsequence similarity |
| Phonetic | 30% | Soundex and Double Metaphone comparison |
| Entity Type Bonus | +5% | Applied when entity type matches |
Use Cases​
Compliance Audit Trail​
The explain endpoint provides the transparency required for compliance audits:
import requests
def get_audit_explanation(query_name, matched_name, entity_type):
"""Get detailed explanation for audit documentation."""
response = requests.post(
"https://api.sanctionswise.orchestraprime.ai/v1/screen/explain",
headers={
"x-api-key": API_KEY,
"Content-Type": "application/json"
},
json={
"query_name": query_name,
"matched_name": matched_name,
"entity_type": entity_type
}
)
data = response.json()
# Extract audit-relevant information
return {
"query": data["query"]["original"],
"matched": data["matched"]["original"],
"score": data["final_score"],
"classification": data["match_classification"],
"reasoning": data["confidence_factors"],
"timestamp": data["timestamp"]
}
Understanding False Positives​
When reviewing potential matches, use the explain endpoint to understand why a name matched:
const axios = require('axios');
async function investigateMatch(queryName, matchedName) {
const response = await axios.post(
'https://api.sanctionswise.orchestraprime.ai/v1/screen/explain',
{
query_name: queryName,
matched_name: matchedName,
entity_type: 'individual'
},
{
headers: {
'x-api-key': API_KEY,
'Content-Type': 'application/json'
}
}
);
const data = response.data;
console.log(`Match Score: ${data.final_score}`);
console.log(`Classification: ${data.match_classification}`);
console.log('Confidence Factors:');
data.confidence_factors.forEach(factor => {
console.log(` - ${factor}`);
});
return data;
}
Error Responses​
400 Bad Request​
{
"error": "Both query_name and matched_name are required",
"received": {
"query_name": true,
"matched_name": false
}
}
401 Unauthorized​
{
"message": "Unauthorized"
}
500 Internal Server Error​
{
"error": "Internal server error",
"message": "An error occurred"
}
Related Endpoints​
- Screen Entity - Screen a single entity
- Batch Screening - Screen multiple entities