Screening Appliance docs
Batch Screening Guide
POST /v1/batch for JSON or JSONL input β synchronous for up to 100 subjects, asynchronous with a pollable job for larger files.
Last updated 2026-08-02
Batch Screening Guide
POST /v1/batch screens many subjects in one call, using the same matcher
and scoring as /v1/search. It accepts
either a JSON array or newline-delimited JSON (JSONL), and switches
automatically between a synchronous and an asynchronous response depending
on batch size.
Request body
Each item in the batch has the same shape as a single /v1/search request
body (name, dob?, country?, identifiers?, datasets?, limit?,
threshold?).
As a JSON array (content-type: application/json):
[
{ "name": "Viktor Bout", "country": "RU" },
{ "name": "Maria Butina", "country": "RU" },
{ "name": "Jane Smith", "country": "US" }
]
As JSONL (content-type: application/x-ndjson), one subject per line β
preferred for larger files, since it can be streamed and generated without
holding the whole batch in memory:
{"name": "Viktor Bout", "country": "RU"}
{"name": "Maria Butina", "country": "RU"}
{"name": "Jane Smith", "country": "US"}
Small batches (β€100 subjects): synchronous
curl -s -X POST http://localhost:8400/v1/batch \
-H 'content-type: application/json' \
-d '[
{ "name": "Viktor Bout", "country": "RU" },
{ "name": "Jane Smith", "country": "US" }
]'
The response returns inline, once every subject has been screened:
{
"results": [
{
"query": { "name": "Viktor Bout", "country": "RU" },
"dataVersion": "2026-08-02T03:00:00Z",
"matches": [
{
"score": 98,
"entity": {
"id": "NK-a1b2c3d4",
"schema": "Person",
"name": "Viktor Anatolyevich Bout",
"datasets": ["us_ofac_sdn", "un_sc_sanctions"]
},
"matchedOn": ["name", "country"]
}
]
},
{
"query": { "name": "Jane Smith", "country": "US" },
"dataVersion": "2026-08-02T03:00:00Z",
"matches": []
}
]
}
results is ordered the same as the input batch β the item at index i in
the request corresponds to results[i] in the response.
Large batches (>100 subjects): asynchronous
Submit the same way β the appliance detects the batch is larger than the synchronous limit and returns a job id immediately instead of blocking the request:
curl -s -X POST http://localhost:8400/v1/batch \
-H 'content-type: application/x-ndjson' \
--data-binary @subjects.jsonl
{ "jobId": "batch-9f2c7a10" }
Poll for completion:
curl -s http://localhost:8400/v1/batch/batch-9f2c7a10
While still running:
{ "jobId": "batch-9f2c7a10", "status": "running" }
Once complete, the same results shape as the synchronous path:
{
"jobId": "batch-9f2c7a10",
"status": "done",
"results": [
{ "query": { "name": "Viktor Bout", "country": "RU" }, "dataVersion": "2026-08-02T03:00:00Z", "matches": ["β¦"] }
]
}
A reasonable polling interval is a few seconds for small-to-medium batches; back off for very large files (tens of thousands of subjects).
Design notes
- Same scoring as
/v1/search. A batch item and an equivalent single/v1/searchcall against the samedataVersionreturn the same matches β batch is a throughput optimization, not a different matching mode. - Per-item
datasets/limit/thresholdoverrides are honored. You can mix subjects that need different dataset scopes or thresholds in one batch. dataVersionis recorded per result. Because a large async batch can span a data sync, individual results carry thedataVersionthey were actually evaluated against β don't assume every result in a job used the same version.
See also
- Search API reference β the single-subject endpoint and full field reference for each request item.
- Monitoring guide β for subjects you need to re-screen continuously rather than once, register them as monitored subjects instead of re-running batches on a schedule.