It is 2034. A regulator asks for the screening you ran on a tanker in September 2026. Which lists did you check, when, under which name, and what came back?

If the answer is a row in your own database that says GREEN and a timestamp, you have a claim. You do not have a record.

The rule

OFAC's recordkeeping requirement used to be five years. An interim final rule published in September 2024 extended it to ten, effective 12 March 2025, and the final rule followed in March 2025. The reason is simple: the statute of limitations for sanctions violations became ten years in 2024, so the records have to last as long as the exposure.

The rule asks for a full and accurate record of every transaction subject to OFAC's jurisdiction. A vessel screening is the record of your decision to proceed with one. If you cannot produce it, the transaction is documented and the diligence behind it is not, which is the worse half to be missing.

A verdict is not a record

Most integrations store the answer and discard the evidence. That felt fine at five years. At ten, with lists that change daily and vessels that get renamed, an answer with no evidence is an assertion nobody can check.

Here is what a defensible record holds, and what ours carries under each heading.

The question in 2034What the record needsOn an ArcNautical screening
Which vessel?IMO, the name it was screened under, and how that name was established.imo, vessel_name, identity_basis, identity_sources[]
Which lists, and when?Every list read, with a timestamp, and any list that could not be read.sources[] with checked_at per list, coverage_gaps
What matched?Each match with its list, programme, match type and confidence.sanctions.matches[]
Under what method?The version of the engine that produced the verdict.methodology_version
Which transaction?Your own reference for the order, fixture or nomination.customer_reference, echoed back
Can I read it again unchanged?A retrievable record that replays verbatim.GET /screenings/{id}, retained 3,650 days

The third row is the one people skip. A match recorded as "hit on OFAC" is not enough when the question is whether it was an exact IMO designation or a fuzzy name match on a common word. Ours carries match_type and confidence_class on every match, and screened_name when the match was on an alias.

Where we got the default wrong

Our first version kept screenings for 30 days, the same operational window that voyage assessments use. That is 120 times shorter than the rule. Screening evidence is kept for 3,650 days now, and it is a separate setting from everything operational, so a change to one can never touch the other.

Getting it out as one file

An auditor asking for "everything we screened in Q3" wants an artifact for an evidence folder, not two hundred pages to reassemble. POST /api/v1/exports builds one file, CSV or JSONL, and is usually ready inside a minute.

curl https://arcnautical.com/api/v1/exports \
  -H "Authorization: Bearer $ARCNAUTICAL_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: export:screenings:2026-Q3" \
  -d '{"resource":"screenings","format":"jsonl",
       "filters":{"created_after":"2026-07-01T00:00:00Z",
                  "created_before":"2026-10-01T00:00:00Z"}}'

Four things about that file are there for the person opening it years later.

The SHA-256 is published on the export and in the X-ArcNautical-Export-Sha256 header, so the copy in your folder can be shown to be the copy we generated. A range over 500,000 rows is refused with the real count, because a file that is quietly short would be treated as complete by everyone downstream of whoever read the flag. The end of the range is pinned to the moment you asked, so the same request tomorrow produces the same file. And JSONL lines are byte for byte what GET /screenings/{id} returns, full evidence included. Take JSONL for the audit file and CSV for the pivot table.

Download links last seven days. The records they were built from keep their own ten years.

Refusals are part of the trail

A record of what you screened is half the story. The other half is what you tried and could not.

GET /api/v1/access-log is every authenticated request on your account for 365 days, including the refused ones, with the error code and the request id you were given at the time. GET /api/v1/webhook-deliveries is every event we tried to send you and what happened to it; a delivery that died after five attempts stays on the record even after you replay it.

Your audit record has to outlive your subscription.

Five questions to ask any screening vendor

You do not have to use us to use this list.

  1. How long do you keep a screening, and is that setting separate from your operational data?
  2. Does the record say which lists were read and when, and which were not?
  3. For a match, does it say exact identifier or name similarity, and on which name?
  4. Can I export a date range as one file with a published hash?
  5. Can I read a record back years later exactly as it was returned, under the engine version that produced it?

If the answer to any of these is "the verdict is in your database", the record does not exist yet.

See what a record looks like

Screen a hull on a self-serve key and read the whole record back with GET /screenings/{id}. The developer docs cover exports, the access log and retention; the screening API page walks through the record itself. If you also route cargo, the voyage playground runs with no account.