Overview
External API coverage
The public customer-facing surface includes customer-facing paths under /api/v1. This page documents core workflows in depth. For every path and method, use the Endpoint Catalog plus Objects & Models or the machine-readable OpenAPI v1 spec. Full operational docs are available in Operations Docs.
Required headers
Authorization: Bearer <YOUR_API_KEY>
Content-Type: application/json
Idempotency-Key: <uuid> # recommended for POST for safe retriesSettings are a required implementation step
MatchAudit provides a global default source set automatically for new API users. If that default is suitable for your workflow, you may keep it. If you need a different jurisdiction or source selection, update it first through PUT /api/v1/settings before screening in production.
Source selection precedence is:
sources[]in the screening request for a one-off override- saved API settings from
/api/v1/settings - the global default source set when no custom settings exist
POST /api/v1/screen
Screen one or more names. You can send country, location, IP, or structured address context in the same request. A clear name screen can still return a blocked or review outcome when the country signal is actionable under the selected jurisdiction.
Request body
POST /api/v1/screen
{
"name": string, // optional alias for a single-name request
"names": string[], // required unless "policyQuery" is used
"entityTypes": string[] | null, // optional: ["individual","entity","vessel","aircraft","wallet"]
"sources": string[] | null, // optional subset of source keys (see /api/v1/datasets). If omitted, saved settings or the global baseline apply
"country": string | null, // optional country context, e.g. "Syria"
"location": string | null, // optional city/region/country string, e.g. "Damascus, Syria"
"ip": string | null, // optional IP context for country resolution
"jurisdiction": string | null, // optional: "GLOBAL" | "US" | "EU" | "UK"; falls back to saved settings when present
"currency": string | null, // optional transaction currency for country-risk evaluation
"sector": string | null, // optional sector for sectoral sanctions checks
"structured": { // optional structured context (mirrors dashboard structured intake)
"fullName": string | null,
"firstName": string | null,
"lastName": string | null,
"dob": string | null,
"ids": [{ "type": string | null, "value": string }],
"address": {
"street": string | null,
"city": string | null,
"region": string | null,
"country": string | null
}
},
"profileKey": string | null, // optional: "sme_trader_default" | "freight_forwarder_default" | "psp_default"
"segment": string | null, // optional: "sme_trader" | "freight_forwarder" | "psp"
"trigger": string | null, // optional: "onboarding" | "payment" | "shipment" | "periodic_rescreen" | "event_rescreen"
"policyQuery": { // optional policy-only filter; if provided with empty "names", zero units consumed
"countries": string[] | null, // e.g. ["US","EU","UK","CH","CA","AU"]
"programCodes": string[] | null, // e.g. ["SDGT","SDN","UKR","BELARUS"]
"keywords": string[] | null // free-text program/list keywords
},
"options": { // optional knobs (sensible defaults)
"maxMatchesPerName": number, // default 10
"threshold": number, // 0..1; default calibrated internal
"returnRaw": boolean // include full raw source entry in each match.evidence.raw
}
}Supported entityTypes
individualentityvesselaircraftwallet(for blockchain screening, if enabled)
Response
200 OK
{
"results": [
{
"input": "Northshore Trading GmbH",
"name": "Northshore Trading GmbH",
"isSanctioned": false, // direct name-screen hit only
"directNameHit": false,
"countryRiskHit": true, // true when country risk drives BLOCK or REVIEW
"actionableHit": true, // direct hit or country-driven hit
"decision": {
"status": "BLOCK", // CLEAR | REVIEW | BLOCK
"label": "Do not proceed",
"headline": "Sanctions concerns identified. Do not proceed.",
"focus": "Country risk block with clean name screening",
"reason": "The submitted subject name did not return direct list matches, but the case still requires a sanctions decision because the provided country information carries independent risk.",
"recommendedNextSteps": [
"Do not proceed with the case.",
"Escalate the case to sanctions or compliance, confirm the country input, and check whether any license, exemption, or legal override process applies."
]
},
"matches": [
{
"source": "EU Sanctions list",
"sourceKey": "eu",
"dataset": "EU (FSF)",
"entityType": "individual",
"matchedName": "Ali Hassan",
"matchScore": 0.93, // 0..1 (1.00 = exact)
"level": "🟢 Very high confidence",
"reason": "Exact name match + DOB match + alias overlap",
"detailsList": [
{ "label": "Date of birth", "value": "1971-05-20" },
{ "label": "Citizenship", "value": "IR" }
],
"evidence": {
"primaryName": "Ali Hassan",
"aliases": ["Hassan Ali", "Ali al-Hassan"],
"identifiers": { "Passport": ["IR12345"] },
"addresses": ["Tehran, Iran"],
"nationality": "IR",
"programs": ["EU-IR"],
"dates": {
"Date of birth": "1971-05-20",
"Date listed": "2012-11-10"
},
"sourceUrls": ["https://.../eu_sanctions/entry/123"]
},
"raw": { /* optional, if options.returnRaw=true */ }
}
],
"sanctions": [], // direct sanctions/list matches
"adverseMedia": [ // adverse media evidence matches
{
"source": "Adverse Media Evidence",
"sourceKey": "adverse_media",
"matchedName": "Northshore Trading GmbH",
"matchScore": 0.97,
"matchedFields": ["full name"],
"reason": "Potential adverse media indicator from an official source, including public enforcement list evidence where applicable.",
"detailsList": [
{ "label": "Source", "value": "IDB Open Data - Dataset of Sanctioned Firms and Individuals" },
{ "label": "Source category", "value": "Multilateral debarment and procurement integrity" },
{ "label": "Date retrieved", "value": "2026-06-06T00:00:00.000Z" },
{ "label": "Risk category", "value": "debarment" },
{ "label": "Source URL", "value": "https://data.iadb.org/dataset/dataset-of-sanctioned-firms-and-individuals" },
{ "label": "Important note", "value": "Potential indicator only; not a final compliance judgment or legal advice." }
],
"evidence": {
"primaryName": "Northshore Trading GmbH",
"sourceUrls": ["https://data.iadb.org/dataset/dataset-of-sanctioned-firms-and-individuals"]
}
}
],
"adverseMediaHit": true
}
],
"policyMatches": [
/* if policyQuery provided without names */
],
"scannedSources": ["ofac_sdn","eu","uk","un","ch","au","ca"],
"unavailableSources": [],
"meta": {
"tookMs": 124,
"tenantId": "org_abc",
"planKey": "starter",
"sourceSelection": {
"mode": "settings", // request | settings | global_baseline
"appliedSources": ["un", "eu", "ofac", "uk", "seco"],
"settingsStore": "user_settings"
},
"policyProfileRequest": {
"profileKey": "freight_forwarder_default",
"segment": "freight_forwarder",
"trigger": "shipment"
},
"countryRisk": {
"provided": true,
"evaluated": true,
"recommendation": "BLOCK",
"riskLevel": "HIGH",
"resolvedCountryName": "Syrian Arab Republic",
"resolvedCountryIso2": "SY",
"jurisdiction": "US",
"reasons": [
"Jurisdiction profile (US) lists SY as blocked."
]
}
}
}Examples
curl -X POST https://your-domain.com/api/v1/screen \
-H "Authorization: Bearer $MATCHAUDIT_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{
"names": ["Northshore Trading GmbH"],
"entityTypes": ["entity"],
"country": "Syria",
"jurisdiction": "US",
"profileKey": "sme_trader_default",
"trigger": "onboarding"
}'export async function screen(names) {
const res = await fetch("https://your-domain.com/api/v1/screen", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.MATCHAUDIT_API_KEY}`,
"Content-Type": "application/json",
"Idempotency-Key": crypto.randomUUID()
},
body: JSON.stringify({
names,
entityTypes: ["entity"],
country: "Syria",
jurisdiction: "US",
profileKey: "sme_trader_default",
trigger: "onboarding"
})
});
if (!res.ok) throw new Error(`Screen failed: ${res.status}`);
return res.json();
}import os, uuid, requests
resp = requests.post(
"https://your-domain.com/api/v1/screen",
headers={
"Authorization": f"Bearer {os.getenv('MATCHAUDIT_API_KEY')}",
"Content-Type": "application/json",
"Idempotency-Key": str(uuid.uuid4())
},
json={
"names": ["Northshore Trading GmbH"],
"entityTypes": ["entity"],
"country": "Syria",
"jurisdiction": "US",
"profileKey": "sme_trader_default",
"trigger": "onboarding"
},
timeout=30
)
print(resp.json())Field glossary
| Field | Type | Description |
|---|---|---|
| results[].isSanctioned | boolean | Direct name-screen hit only. Country-only restrictions do not flip this field by themselves. |
| results[].actionableHit | boolean | True when the request produced a direct hit or a country-driven BLOCK/REVIEW signal. |
| results[].decision.status | "CLEAR" | "REVIEW" | "BLOCK" | Final screening outcome for the submitted name plus any country-risk context. |
| results[].matches[].matchScore | number (0..1) | Normalized similarity score; 1.00 is exact. |
| results[].matches[].level | string | Calibrated confidence band (emoji + label). |
| results[].matches[].reason | string | Human-readable justification for the hit. |
| results[].matches[].detailsList | array | Flattened key facts shown in the UI (DOB, citizenship, etc.). |
| results[].matches[].evidence | object | Structured evidence (aliases, identifiers, programs, dates, URLs). |
| results[].sanctions | array | Direct sanctions/list matches separated from other review signals. |
| results[].adverseMedia | array | Adverse-media evidence matches, including source, source type, category, legal status, severity, retrieved date, matched fields, confidence, reason, and URL/reference. Some sources are public enforcement lists. |
| results[].adverseMediaHit | boolean | True when adverse-media evidence matched the submitted subject. |
| meta.countryRisk | object | Country-risk evaluation summary for the request, including recommendation, resolved country, and reasons. |
| meta.sourceSelection | object | Shows whether the route used request sources, saved settings, or the global baseline. |
| meta.policyProfileRequest | object | Echo of profile/segment/trigger request hints passed to the API. |
| scannedSources | string[] | Which datasets were actually scanned for this request. |
| unavailableSources | string[] | Datasets temporarily unavailable during the request. |
| meta.tookMs | number | Processing time in milliseconds. |
Source keys
Source keys are dynamic and reflect the datasets enabled for your tenant. Fetch the current list from GET /api/v1/datasets and pass any subset in sources. If omitted, we scan according to your saved settings, or the global default source set if you have not saved custom settings yet.
For implementation and audit purposes, treat settings review as a mandatory first step even though a global default is provided automatically.
POST /api/v1/integrations/salesforce/screen
Screen one Salesforce Contact, Account, Lead, or similar record through MatchAudit and return a structured compliance answer designed for CRM workflows. This connector is built for lean teams: one record in, one screening outcome out, plus an audit reference and evidence links you can store back on the Salesforce record.
Request body
POST /api/v1/integrations/salesforce/screen
{
"recordType": "contact", // recommended: contact | account | lead | opportunity
"recordId": "0038b00002AbCdE", // optional Salesforce record id
"recordUrl": "https://your-org.lightning.force.com/...",
"requestId": "sf-flow-2026-03-27-001", // recommended idempotent reference from Flow or middleware
"subjectType": "individual", // optional override: individual | entity
"fullName": "Aleksandr Sergei Petrov", // required for person-like records
"firstName": "Aleksandr", // optional
"lastName": "Petrov", // optional
"companyName": "PetroLogix Trading Ltd", // required for account/entity flows
"country": "Cyprus", // strongly recommended
"dateOfBirth": "1982-03-12", // optional
"nationality": ["Russia", "Cyprus"], // optional
"gender": "Male", // optional
"placeOfBirth": "Moscow, Russia", // optional
"identifiers": [ // optional
{ "type": "passport", "value": "724587392" }
],
"aliases": ["Alexander Petrov"], // optional
"mailingStreet": "14 Limassol Marina", // optional
"mailingCity": "Limassol", // optional
"mailingCountry": "Cyprus", // optional
"sources": ["un", "eu", "ofac"] // optional one-off source override
}Response
200 OK
{
"ok": true,
"integration": {
"key": "salesforce",
"label": "Salesforce",
"recordType": "contact",
"recordId": "0038b00002AbCdE",
"recordUrl": "https://your-org.lightning.force.com/..."
},
"subject": {
"primaryName": "Aleksandr Sergei Petrov",
"companyName": "PetroLogix Trading Ltd",
"subjectType": "individual",
"country": "Cyprus",
"location": "Cyprus"
},
"screening": {
"screeningStatus": "REVIEW", // CLEAR | REVIEW | BLOCK
"outcomeLabel": "Review required",
"riskLevel": "MEDIUM", // LOW | MEDIUM | HIGH
"actionableHit": true,
"directNameHit": true,
"countryRiskHit": false,
"summary": "Aleksandr Sergei Petrov returned possible sanctions concerns that need analyst review.",
"recommendedNextSteps": ["Pause the workflow until the reviewer confirms the result."],
"matchSummary": {
"directMatchCount": 1,
"topMatch": {
"source": "OFAC SDN",
"sourceKey": "ofac",
"matchedName": "Aleksandr Sergei Petrov",
"score": 0.97,
"confidence": "High",
"matchType": "Exact full-name match",
"matchedOn": "official record",
"matchedFields": ["full name", "passport"],
"reason": "Exact name match with corroborating identifier.",
"programs": ["SDN"]
},
"additionalMatches": [],
"countryRisk": null
},
"sourceSelection": {
"mode": "settings",
"appliedSources": ["un", "eu", "ofac", "uk", "seco"],
"settingsStore": "user_settings"
},
"scannedSources": ["un", "eu", "ofac", "uk", "seco"],
"unavailableSources": [],
"auditReferenceId": "84321",
"evidence": {
"pdfUrl": "https://your-domain.com/api/v1/export?type=pdf&auditId=84321",
"jsonUrl": "https://your-domain.com/api/v1/export?type=json&auditId=84321"
},
"timestamp": "2026-03-27T14:18:00.000Z"
}
}Examples
curl -X POST https://your-domain.com/api/v1/integrations/salesforce/screen \
-H "Authorization: Bearer $MATCHAUDIT_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: sf-contact-0038b00002AbCdE" \
-d '{
"recordType": "contact",
"recordId": "0038b00002AbCdE",
"fullName": "Aleksandr Sergei Petrov",
"companyName": "PetroLogix Trading Ltd",
"country": "Cyprus",
"dateOfBirth": "1982-03-12"
}'export async function screenSalesforceRecord(payload) {
const res = await fetch("https://your-domain.com/api/v1/integrations/salesforce/screen", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.MATCHAUDIT_API_KEY}`,
"Content-Type": "application/json",
"Idempotency-Key": payload.requestId || crypto.randomUUID()
},
body: JSON.stringify(payload)
});
if (!res.ok) throw new Error(`Salesforce screening failed: ${res.status}`);
return res.json();
}1. screening.screeningStatus
2. screening.riskLevel
3. screening.summary
4. screening.auditReferenceId
5. screening.evidence.pdfUrl
6. screening.evidence.jsonUrlConnector notes
- Use
country,billingCountry, ormailingCountrywhenever possible so the connector can evaluate country risk in the same request. - Accounts default to entity screening. Contacts and leads default to individual screening unless you override
subjectType. - MatchAudit audit-logs every connector-triggered screening and returns the audit reference id for record-level evidence storage.
- The same CRM connector service is designed to be reused later for HubSpot or other CRM connectors, so the contract is intentionally narrow and stable.
POST /api/v1/integrations/sap-gts/sync
Send SAP GTS exports into MatchAudit for screening, case creation, and review tracking. This endpoint is designed for customers who already work in SAP GTS and want a repeatable handoff from trade operations into compliance review without relying on manual uploads every time.
For customer-configured SAP CPI or middleware implementations, set connectorType to sap_cpi and let the dashboard store the matching source system, deep links, and write-back configuration. Customer-side SAP CPI or middleware configuration is required; this is not an SAP-certified packaged connector.
Request body
POST /api/v1/integrations/sap-gts/sync
{
"externalRunId": "sap-job-2026-03-11-001", // recommended for safe retries
"sourceSystem": "sap-gts", // optional; defaults to sap-gts
"fileName": "sap-export-2026-03-11.csv", // optional
"csvText": "Name,Country,Document No\n...", // optional if rows is not sent
"rows": [ // optional if csvText is sent
{
"Name": "Example GmbH",
"Country": "DE",
"Address": "Berlin, Germany",
"Document No": "4711",
"Transaction ID": "TX-10001",
"SAP Result": "REVIEW",
"Reason": "Potential sanctions hit",
"Timestamp": "2026-03-11T10:00:00Z"
}
],
"includeRows": false, // optional; include normalized rows in response
"requestMeta": { // optional middleware metadata
"jobType": "nightly-export",
"plant": "DE01"
}
}SAP CPI envelope example
POST /api/v1/integrations/sap-gts/sync
{
"connectorType": "sap_cpi",
"sourceSystem": "sap-cpi",
"externalRunId": "cpi-run-2026-03-14-001",
"cpi": {
"records": [
{
"Name": "Example GmbH",
"Country": "DE",
"Document No": "4711",
"Transaction ID": "TX-10001",
"SAP Result": "REVIEW"
}
]
}
}Response
200 OK
{
"ok": true,
"syncRun": {
"id": "2f4c2a58-...",
"status": "SUCCEEDED",
"source_type": "api_sync",
"source_system": "sap-gts",
"external_run_id": "sap-job-2026-03-11-001",
"input_row_count": 125,
"processed_row_count": 125,
"created_count": 80,
"updated_count": 45,
"error_count": 0,
"warning_count": 2,
"result_meta": {
"durationMs": 2140,
"qualitySummary": {
"validRows": 125,
"invalidRows": 0
}
}
},
"processedCount": 125,
"mapping": { "name": "Name", "sap_result": "SAP Result" },
"qualitySummary": { "validRows": 125, "invalidRows": 0 },
"warnings": []
}Examples
curl -X POST https://your-domain.com/api/v1/integrations/sap-gts/sync \
-H "Authorization: Bearer $MATCHAUDIT_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"externalRunId": "sap-job-2026-03-11-001",
"sourceSystem": "sap-gts",
"rows": [
{
"Name": "Example GmbH",
"Country": "DE",
"Document No": "4711",
"Transaction ID": "TX-10001",
"SAP Result": "REVIEW"
}
]
}'export async function syncSapGts(rows) {
const res = await fetch("https://your-domain.com/api/v1/integrations/sap-gts/sync", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.MATCHAUDIT_API_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
externalRunId: crypto.randomUUID(),
sourceSystem: "sap-gts",
rows
})
});
if (!res.ok) throw new Error(`SAP GTS sync failed: ${res.status}`);
return res.json();
}import os, uuid, requests
resp = requests.post(
"https://your-domain.com/api/v1/integrations/sap-gts/sync",
headers={
"Authorization": f"Bearer {os.getenv('MATCHAUDIT_API_KEY')}",
"Content-Type": "application/json"
},
json={
"externalRunId": str(uuid.uuid4()),
"sourceSystem": "sap-gts",
"rows": [
{
"Name": "Example GmbH",
"Country": "DE",
"Document No": "4711",
"Transaction ID": "TX-10001",
"SAP Result": "REVIEW"
}
]
},
timeout=30
)
print(resp.json())Operational notes
- Use
externalRunIdso middleware retries do not create duplicate sync runs. - The response includes mapping and quality summary information so you can detect bad exports before analysts start review.
- Rows are normalized into the same review workflow used by the dashboard SAP GTS upload page.
- Recent sync runs can be reviewed in the dashboard under
Integrations > SAP GTS. - Scheduled sync and automatic write-back are configured in the dashboard SAP GTS automation panel, not in the request body of this endpoint.
- Default mapping profiles are applied automatically per
sourceSystemwhen you do not send a mapping object explicitly.
GET /api/v1/integrations/sap-gts
Read back reviewed SAP GTS decisions for middleware write-back into SAP, middleware queues, or downstream operational systems.
If you enable automatic write-back in Integrations > SAP GTS, MatchAudit can push the same reviewed decision payload to your middleware automatically. Keep this endpoint for reconciliation, polling, or fallback reads.
Draft saves stay inside MatchAudit and do not appear here. Only finalized decisions are eligible for public read-back and automatic write-back.
Query parameters
GET /api/v1/integrations/sap-gts?externalRunId=sap-job-2026-03-11-001&updatedSince=2026-03-11T00:00:00Z&limit=100
externalRunId optional filter to one SAP middleware run
transactionId optional filter to one SAP transaction id
documentNo optional filter to one SAP document reference
updatedSince optional ISO-8601 lower bound on human-reviewed decisions
limit optional default 100, max 500Response
200 OK
{
"ok": true,
"decisions": [
{
"caseId": "0bc8...",
"searchedName": "PJSC Alrosa",
"transactionId": "TX-10001",
"sapDocumentNo": "4711",
"sourceSystem": "sap-gts",
"externalRunId": "sap-job-2026-03-11-001",
"syncRunId": "2f4c2a58-...",
"sapResult": "REVIEW",
"matchauditOutcome": "HIT",
"matchauditTopSource": "eu",
"matchauditTopScore": 0.89,
"finalDecision": "ESCALATE",
"caseStatus": "ESCALATED",
"reviewerNotes": "Escalated to sanctions officer due to EU hit.",
"decisionReviewedAt": "2026-03-11T10:18:00.000Z",
"decisionReviewedBy": "user-id",
"evidencePdfUrl": "https://your-domain.com/api/export?type=case_pdf&case_id=0bc8..."
}
]
}POST /api/v1/cross-border-risk
Run Cross-Border jurisdiction risk triage by country, IP, or location. Returns sanctions, AML, governance assessments, plus a final recommendation (BLOCK / CAUTION / ALLOW).
Request body
POST /api/v1/cross-border-risk
{
"country": "Germany", // optional; provide one of country, ip, location
"ip": "8.8.8.8", // optional
"location": "Munich, Germany", // optional
"jurisdiction": "GLOBAL", // optional: GLOBAL | US | EU | UK
"currency": "EUR", // optional ISO-4217 (3 letters)
"sector": "Banking" // optional free text
}Response
200 OK
{
"input": { ... },
"jurisdiction": "GLOBAL",
"resolved": {
"country_name": "Germany",
"country_iso2": "DE",
"confidence": "HIGH",
"resolution_method": "LOCATION",
"region": "Bavaria",
"city": "Munich",
"geo_source": "maxmind_city",
"precision_warning": ""
},
"assessments": {
"sanctions": { "recommendation": "ALLOW", "risk_level": "LOW", "reasons": [] },
"aml": { "recommendation": "ALLOW", "risk_level": "LOW", "reasons": [] },
"governance":{ "recommendation": "CAUTION", "risk_level": "MEDIUM", "reasons": [] }
},
"final": {
"recommendation": "CAUTION",
"risk_level": "MEDIUM",
"reasons": ["..."]
},
"risk": { ... },
"meta": {
"tookMs": 112,
"tenantId": "org_abc",
"planKey": "starter"
}
}Examples
curl -X POST https://your-domain.com/api/v1/cross-border-risk \
-H "Authorization: Bearer $MATCHAUDIT_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "location": "Donetsk People\'s Republic", "jurisdiction": "GLOBAL", "currency": "USD", "sector": "Defense" }'export async function getCrossBorderRisk(payload) {
const res = await fetch("https://your-domain.com/api/v1/cross-border-risk", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.MATCHAUDIT_API_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify(payload)
});
if (!res.ok) throw new Error(`Cross-border risk failed: ${res.status}`);
return res.json();
}import os, requests
resp = requests.post(
"https://your-domain.com/api/v1/cross-border-risk",
headers={
"Authorization": f"Bearer {os.getenv('MATCHAUDIT_API_KEY')}",
"Content-Type": "application/json"
},
json={
"ip": "8.8.8.8",
"jurisdiction": "EU",
"currency": "EUR",
"sector": "Energy"
},
timeout=30
)
print(resp.json())Cross-Border Risk errors
Limits & rate-limiting
- On
429 rate_limitedor503 unavailable, retry with exponential backoff. - Use
Idempotency-Keyon POSTs to make retries safe.
GET /api/v1/usage/summary
Returns current-month usage for a tenant (organization). Supports either a server-only bearer secret (API_AUTH_SECRET) or a regular API key. With API keys, tenant scope is enforced to the key's own tenant.
Query parameters
| Param | Type | Required | Description |
|---|---|---|---|
| tenantId | string (uuid) | Yes | Tenant/organization ID to fetch usage for. |
| planKey | string | No | Plan key override (free, starter, growth, scale, enterprise). Defaults to tenant plan. |
You can also pass X-Tenant-Id and X-Plan-Key headers instead of query params.
Request
GET /api/v1/usage/summary?tenantId=<uuid>&planKey=starter
Authorization: Bearer <API_AUTH_SECRET>Response
200 OK
{
"planKey": "starter",
"included": 3000,
"used": 123,
"remaining": 2877,
"periodStartIso": "2025-10-01T00:00:00.000Z",
"periodEndIso": "2025-11-01T00:00:00.000Z"
}Evidence Hub API
A separate, versioned API for MatchAudit's Evidence Hub — independent of the screening endpoints above. Use it to read the controls/domains your organization can classify evidence against, and to create or read Evidence Hub records from an external system (e.g. a provider connector, an internal tool, or a scheduled job).
Authentication is the same Authorization: Bearer <API_KEY> model as every other endpoint on this page. When you generate a key (dashboard or POST /api/v1/keys), you may optionally restrict it to one or more scopes: evidence_hub:read, evidence_hub:write, or evidence_hub:*. A key generated without scopes has full, unrestricted access — this matches every key generated before scopes existed, so existing integrations are unaffected.
GET /api/v1/evidence-hub/domains
List the domain groups, domains, and controls your organization can classify records against. Requires evidence_hub:read (or an unrestricted key).
Response
200 OK
{
"ok": true,
"domainGroups": [
{
"key": "trade_supply_chain",
"name": "Trade & Supply Chain",
"domains": [
{
"key": "end_use_destination",
"name": "End-use & Destination",
"controls": [
{ "id": "c_123", "key": "end_use_review", "name": "End-use review", "riskTagKeys": ["export_control"], "organizationOwned": false }
]
}
]
}
]
}GET /api/v1/evidence-hub/records
Paginated list of Evidence Hub records for your organization. Requires evidence_hub:read.
| Param | Type | Required | Description |
|---|---|---|---|
| page | integer | No | Defaults to 1. |
| pageSize | integer | No | Defaults to 20, max 100. |
Response
200 OK
{
"ok": true,
"records": [ { "id": "ev_123", "review_status": "draft", "...": "see Evidence Hub record object" } ],
"total": 41,
"page": 1,
"pageSize": 20
}POST /api/v1/evidence-hub/records
Create a record. Requires evidence_hub:write. At least one subject (subject_name + subject_type) is required. template_id is optional and classifies the record against a control returned by GET /domains.
Request body
POST /api/v1/evidence-hub/records
Idempotency-Key: provider-123:check-90818
{
"title": "End-use review — Northline Trade Logistics LLC", // optional
"business_reference": "SHIP-2026-1842", // optional
"source_type": "external_vendor", // optional, default external_vendor
"evidence_type": "pdf_report", // optional, default manual_record
"screening_purpose": "end_use_review", // optional
"screening_date": "2026-07-25T14:20:00Z", // optional
"template_id": "c_123", // optional, from GET /domains
"subjects": [ // required, at least one
{ "subject_name": "Northline Trade Logistics LLC", "subject_type": "legal_entity", "subject_role": "end_user" }
]
}Response
201 Created
{
"ok": true,
"evidence": { "id": "ev_123", "review_status": "draft", "...": "see Evidence Hub record object" },
"subjects": [ { "id": "subj_123", "subject_name": "Northline Trade Logistics LLC", "subject_type": "legal_entity" } ]
}GET /api/v1/evidence-hub/records/{id}
Fetch a single record and its control classification. Requires evidence_hub:read. Returns 404 for a record outside your organization.
Evidence Hub API — not yet available
The following are on the roadmap but not implemented yet: editing a record after creation, uploading artifacts/files, adding subjects or findings after creation, finalize/supersede, bulk import, and evidence-pack export — all of these remain dashboard-only for now. A dedicated provider-connection management API is also not implemented; use scoped API keys (above) instead.
Evidence Hub errors
Errors
Tip: Keep API keys out of browser code. If you must call from the client, proxy via your server and enforce per-tenant quotas.