Screening contracts · implementation

What a screening API does not show you, and how to make it say so

A screening response has two questions to answer: what did the service find, and what did it actually check? A no_match status alone does not answer the second. Read the coverage and source fields before treating an empty result as a completed screen.

A screen drops records for ordinary, defensible reasons. It scores a name and the score lands under the floor. It reads the first page of a source that holds more. It refuses to return a record because that record names a person. Each of those is a decision, and each one is invisible unless the response says so. When they are invisible, one answer — no_match — covers two completely different situations: nothing there resembled this name, and several things did and you are not being shown them.

The seven questions

Run these against any screening response, ours included. Each one has a yes-or-no answer in the response body or it does not, and “it does not” is itself the finding. The field names in the table are the ones our published OpenAPI documents carry today — this page reads them out of those documents when it is built, so it cannot describe a field that is no longer served.

Ask Field What it tells you Carried by
What did it read and decide against? records_below_match_threshold How many records the source returned that scored below the match floor and are not in the response. A short trading name scores low against a long registered legal name, so this is the number a human might want to look at. EPA Compliance Risk, FDA Import Alert Screening, US Import Risk Screening
What did it refuse to show you? withheld_possible_individual True when an entry that would have matched was withheld because its listed name may identify a person, and the service screens organizations only. It never says who, or how many. EPA Compliance Risk, FDA Import Alert Screening
Was any part of this screen missing? incomplete_coverage True when something was not read to the end: a source that could not be reached, a partial list, a withheld entry, or a data snapshot that is not live. A clean-looking result beside this flag is not a clean result. EPA Compliance Risk, FDA Import Alert Screening, US Import Risk Screening
In plain words, what is missing? coverage_note One sentence naming the gap and pointing at the primary source to check directly. EPA Compliance Risk, FDA Import Alert Screening, US Import Risk Screening
Did it see the whole page of results? result_page_truncated True when the source held more matching records than the screen read, so every count beside it is a lower bound. US Import Risk Screening
How many did the source itself say there were? total_upstream_results The source's own total, or null when it does not report one — so you can tell 'none' from 'we could not tell'. US Import Risk Screening
What was screened, and how current is it? source The source name and URL, whether the response came from live data or a snapshot, and the date that data carries — so nobody has to assume. EPA Compliance Risk, FDA Import Alert Screening, US Import Risk Screening

A worked example: the same status, three different situations

These three responses were captured on 2026-09-17 from FDA Import Alert Screening. The first two have something in common that the status field alone will never tell you.

1. A match — and 9 other entries the screen read and set aside

Screening Claridges Organic Ltd returns the listed firm Claridges Organic Limited. It also reports records_below_match_threshold: 9: FDA's lists hold 9 further entries whose names came close enough to be scored and not close enough to be shown. If one of them is your supplier under a trading name, the count is how you find out it is worth checking.

2. No match — and 67 entries read and set aside

The same product, a different name, and the answer is no_match with records_below_match_threshold: 67. Nothing cleared the floor. 67 entries were read and judged, and you can see that a judgment happened.

3. No match — and nothing was read that came close

A name that genuinely matches nothing returns no_match with records_below_match_threshold: 0. This is the answer people assume they are getting every time they see no_match. It is worth being able to tell the three apart.

There is a fourth case, and it is the one a near-miss count cannot rescue: a name typed without its spaces scores so low that nothing is read as close at all. We measured it on 97 real listed entities — a company's short name finds its record 98% of the time spelled with spaces and 4% without, and half the misses fall below the floor where any near miss would be reported. The numbers, the data and what to do about it: a company name without spaces misses the screening list.

Absence of findings is not absence of checking

That sentence is the whole point of the fields above, and it is a test you can apply to any screening product you are evaluating. A response that cannot distinguish we checked and found nothing from we could not check is not reporting a screen; it is reporting a mood. Two specific cases are worth asking about directly:

The same discipline across sources

A cross-agency screen multiplies the problem: five sources, five ways to be quietly incomplete. In the capture from 2026-09-17, the OSHA section of a cross-agency company screen returns a match and records_below_match_threshold: 2 beside it, while each section carries its own truncated list and its own source manifest. The top-level incomplete_coverage is true whenever any of them is, so the summary can never read cleaner than its worst section.

A runnable branch for the shipment response

For POST /screen/shipment, check the HTTP status first, then parse the JSON response as data. This JavaScript example checks both UFLPA and CSL, their source basis, and the aggregate coverage flag. These result labels belong to the example; they are not new API response fields.

function interpretShipmentScreen(data) {
  const sections = [data?.uflpa, data?.csl];
  if (sections.some(section => section?.status === 'error')) {
    return 'source_failed';
  }
  if (sections.some(section => section?.source?.basis !== 'live')) {
    return 'incomplete';
  }
  if (data?.exposure_summary?.incomplete_coverage !== false) {
    return 'incomplete';
  }
  if (sections.some(section =>
    ['match', 'possible_match'].includes(section?.status)
  )) {
    return 'review_matches';
  }
  if (sections.every(section => section?.status === 'no_match')) {
    return 'no_reported_matches';
  }
  return 'incomplete'; // Unknown statuses are not a completed screen.
}

console.log(interpretShipmentScreen(data));

source_failed means at least one source returned an error. incomplete takes priority over an empty matches array or a potential match: read exposure_summary.reasons and each source's notes. Keep any returned candidates available for review even when the summary reports a gap. Missing fields and unfamiliar statuses cannot become a completed no-match in this example.

no_reported_matches means neither checked list reported a candidate under this comparison. It is not clearance, identity verification, or a determination of product origin. This branch is specific to the shipment response; /screen/parties has a different shape. Use the current OpenAPI contract for the fields and the developer hub for authentication and request examples.

What to do with the answer

None of this makes a screen more accurate. It makes it auditable, which is a different and more useful property: a reviewer can see what was decided, re-screen under the full registered legal name when a count says something was set aside, and check the primary source when a section says it could not be read. A screening result nobody can audit is worse than no result, because it gets filed as evidence.

The fields on this page are served by FDA Import Alert Screening, US Import Risk Screening and EPA Compliance Risk. The responses quoted above are unedited captures made on 2026-09-17; every number on this page is read from that capture when the page is built.

Last updated . Corrections: see About.