Try it on whichever screening API you are evaluating. Send 1234567.
If a vessel name comes back with a clean verdict under it, you have learned something important about the vendor, because 1234567 does not identify a ship. Fifteen different vessels have broadcast it as their IMO number in our AIS registry, among them a website and a piece of test equipment. It also passes its own check digit, which is exactly why it survives form validation and flows all the way down a pipeline.
Here is what ours returns, with no key:
curl https://arcnautical.com/api/v1/vessels/1234567/check
{
"imo": "1234567",
"sanctions": {
"status": "INCOMPLETE",
"detail": "Vessel identity could not be resolved from the IMO, so
name-based screening could not run. No identifier match
was found, but this is not a clearance."
},
"vetting": { "grade": null, "score": null, "status": "not_assessed" },
"assessed": false
}
No name. No grade. And a fourth verdict that most screening products do not have.
Four verdicts, not three
| Verdict | What it means |
|---|---|
| RED | A confirmed match on the vessel identifier, or a designated owner. |
| AMBER | A name match without an identifier match, a watchlist listing, or an aggregated record the primary list does not corroborate. |
| GREEN | No match, and every mandatory list was read. |
| INCOMPLETE | A mandatory list, or the vessel's identity, was unavailable. No clearance can be defended. |
The fourth one took longer to get right than the other three put together, and it exists for one reason.
Name matching is half the job
A designation can be found two ways. By identifier, when the list carries the IMO number. By name, when it does not, or when the hull has been renamed since it was listed.
If we cannot name a hull, the second half cannot run. We can still check the number against every list, and for 1234567 that check finds nothing. But "no identifier match" is not "no match". A screening API that returns GREEN at that point is handing you a clearance built on half a search.
A clearance we cannot defend is worse than no answer.
Where a name comes from
Five stores we hold are read on every screening: our own vessel register, an AIS-derived registry, and three port-state-control stores from the Paris and Tokyo MoUs. Most hulls are named by one of those in well under a second.
When all five are silent, we read four public registers live, inside your request and under a time budget of a few seconds: DNV's vessel register, the ITF ship lookup, the IACS vessels-in-class file and USCG PSIX. New-builds and recently renamed hulls are the ones that fall through to this tier.
Registers disagree exactly when a hull has been renamed, because a class register carries the current name while an older file still carries the yard name. So the hull is screened under every name returned, and a match on one of the other names carries screened_name so you can see which name it was.
Every screening records what the resolver did in identity_sources[]: each register, whether it named the hull, and whether it answered at all. A register that was down is not a register that came back empty. Those have opposite retry policies, and the record keeps them apart.
Two checks before any list is read
The seventh digit of an IMO number is a checksum over the first six. A number that fails it belongs to no vessel, and the usual cause is two digits transposed off a nomination. We screen it as a bare identifier, decline to trust any name for it, and set imo_check_digit_valid: false. The live response for 1111111 says it plainly: check the number against the certificate or Q88 and re-screen.
The second check is the one 1234567 fails. Our AIS registry is keyed on the transponder, not the hull, so one vessel legitimately appears under several rows after a rename or a reflag, and the newest name wins. But an AIS identity is self-reported. When four or more unrelated vessels claim the same number, our data no longer identifies a hull, and we decline to pick one. A screening run against the wrong name returns a clean answer that means nothing.
People test integrations with memorable numbers. If your test hull is 1234567 and the API returns a confident name and a GREEN, the test passed and the API failed. Our response for that number is the response you want, because it is the one that tells the truth about the input.
What happens after INCOMPLETE
An identity INCOMPLETE is not charged. unit_charged is false on the record. Then you have two options, and one of them is to do nothing.
If you hold a name you can confirm, send it as vessel_name and the answer comes back now. It is used only when our own sources hold nothing, so it can never override what we know, and the record marks it as caller-supplied with identity_basis: "user".
Or leave it. Asking about a hull we cannot name puts it at the head of our next scheduled port-state fetch. The record carries a resolution block with the first scheduled re-screen, the number of attempts and the give-up instant. When a fetch names the hull, we re-run your exact request, the verdict arrives as a new screening whose supersedes field points at the one you hold, your record gets superseded_by, and a screening.resolved event fires. One unit is charged, on the verdict, not on the question.
You submit once.
We built this after watching a real account. Seventy-three of their hulls stood INCOMPLETE at their last ask, and their worker never re-asked any of them. A person found one by re-checking it by hand the next day, and it had been named by a harvest in between. The remedy that lived in an email and a docs page reached nobody. The re-screen is ours to run now.
Handling it in code
if (screening.sanctions.status === 'INCOMPLETE') {
showPending(order); // never render as clean
if (screening.resolution) {
// we will re-screen; subscribe to screening.resolved
// or poll GET /screenings?customer_reference=...
} else {
// nothing we do can change it: read notices[] for why
// (check digit, contested number) and fix the input
}
}
Two rules cover almost every case. Never retry an INCOMPLETE in a loop, because an identical immediate retry cannot produce a different answer and the response tells you so. And never let it fall through to the code path that renders GREEN. Both are cheaper than the false clearance they prevent.
Try the number yourself
curl https://arcnautical.com/api/v1/vessels/1234567/check needs no key. Then read how identity resolution and the resolution block work in the developer docs, or start from the screening API page. Routing cargo too? The voyage playground runs with no account.