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/search call against the same dataVersion return the same matches β€” batch is a throughput optimization, not a different matching mode.
  • Per-item datasets/limit/threshold overrides are honored. You can mix subjects that need different dataset scopes or thresholds in one batch.
  • dataVersion is recorded per result. Because a large async batch can span a data sync, individual results carry the dataVersion they 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.

More Screening Appliance docs

← All Screening Appliance docs