DEV Community

VesselAPI
VesselAPI

Posted on • Originally published at vesselapi.com

The MMSI Lookup Is Lying to You (And That's Not Its Fault)

You type a nine-digit number into a search box. Out comes a ship: a name, a flag, a length, a cargo type, maybe a fuzzy photo taken from a pilot boat in Rotterdam three years ago. The number is the MMSI — Maritime Mobile Service Identity — and it feels like the most boring possible piece of maritime data. It's an ID. You look it up. You get a ship.

Except the MMSI is not, in any strict sense, the ship's identity. It's the identity of the radio on the ship. And once you understand the difference, a lot of strange things about vessel tracking start to make sense — including why our /vessel/{id} endpoint returns an array called former_names[], and why that array is sometimes longer than you'd believe.

What an MMSI actually is

The MMSI was never designed to be a permanent vessel identifier. It was designed by the ITU — the International Telecommunication Union, the same body that allocates radio spectrum and country calling codes — to route maritime radio traffic. For ship-station MMSIs, the first three digits, the Maritime Identification Digits, encode the country that issued the number. The rest is administrative.

When SOLAS mandated Class A AIS for international trading vessels, the rollout was phased over several years beginning in 2002, with smaller tiers and existing fleets not fully captured until the late 2000s. The MMSI was the natural identifier to broadcast — every SOLAS vessel equipped with a DSC-capable VHF radio under the GMDSS rules of the 1990s already had one — and reusing it required no new numbering authority. It was a pragmatic choice, not a design decision.

Here's what an MMSI actually is: a number associated with a transmitter, registered to a vessel, flagged to a country, at a particular moment in time. Change any of those and the relationship shifts. Sell a ship to an owner in another country and the MMSI changes — new flag, new MID, new number. Scrap a vessel and the MMSI may eventually be eligible for reissuance, though practices vary by flag state and most administrations have grown reluctant to reuse numbers because of the AIS contamination it causes. Far more common, in practice, is the ghost record problem: the hull is gone, but the MMSI keeps matching in aggregator databases because nobody told the aggregator.

And then there's the misconfigured transponder. A significant number of vessels — overwhelmingly small craft running cheap Class B units, not SOLAS-grade Class A installations — are out there broadcasting 123456789 or 000000000 because someone shipped a unit with factory defaults and nobody changed them. This should have been solved at the hardware certification level a decade ago. It wasn't. The result is the same: two ships, sometimes on opposite sides of the planet, broadcasting the same MMSI in the same minute.

The MMSI is more like a license plate than a VIN. The plate identifies the car on this road, under this jurisdiction, right now. The VIN identifies the car itself. AIS gives you the plate. You have to do real work to get to the VIN.

The thing that actually identifies a ship

The closest thing the maritime world has to a VIN is the IMO number — seven digits, issued by the International Maritime Organization, and (in principle) attached to a hull for life. Scrap the ship and the IMO retires with it. Rename it, reflag it, repaint it, sell it to a shell company: the IMO stays.

The analogy nearly works. The catch is the scope. Under IMO Resolution A.1078(28), IMO numbers are required for commercial cargo vessels of 300 GT and above on international voyages, passenger ships of 100 GT and above, and — progressively — fishing vessels of 100 GT and above. The exemptions matter more than the thresholds: pleasure yachts not in trade, domestic-only vessels, government vessels, and, critically, most of the global fishing fleet, which sits below the 100 GT cutoff and is therefore legitimately exempt. Among the fishing vessels that are eligible, flag-state compliance is inconsistent at best — a fact anyone who has tried to identify a vessel involved in IUU fishing will recognize immediately.

So a serious vessel lookup has to reason about identity using several keys at once — MMSI, IMO, call sign, name — and know which one to trust when they disagree. They disagree often.

My personal opinion, for what it's worth: the IMO number should be mandatory for every motorized seagoing vessel, full stop. The fact that it isn't costs the industry — and sanctions enforcement, and fisheries management, and casualty investigations — real money every year. But the politics of flag state sovereignty being what they are, we work with what we have.

Why former_names[] is an array

When you query /vessel/{id} and get back a vessel record, one of the fields is former_names. We didn't add it for novelty. We added it after a customer ran a sanctions screen against a current vessel name, got a clean result, and chartered a ship that — under a previous name two owners back — had been hauling sanctioned crude out of a port nobody wants to be associated with. The hull was sanctioned. The current name was not. Same ship. Different mask. The customer was, understandably, not delighted.

A bulk carrier built in 2008 might have been called Atlantic Pioneer under one owner, Star Pioneer under the next, MV Helena after a sale to a Greek operator, and Ocean Star III after a charter restructuring last spring. (Illustrative names; the pattern is real.) Same hull. Same IMO. Four names. Possibly three different MMSIs along the way, because each sale brought a reflag.

If your application caches "MMSI 538001234Ocean Star III" and a customer asks about a port call from 2019, you'll tell them no such ship visited, when in fact Atlantic Pioneer visited twice that month. The vessel didn't lie. Your model of vessel identity did.

This is why a good vessel lookup API doesn't just resolve the current state. It resolves the history — every alias the hull has worn, with date ranges where we can establish them. The same principle drives former_flags[], former_owners[], and former_mmsis[], populated where registry data and AIS static records let us reconstruct the chain. Coverage is uneven: former_names and former_mmsis are usually dense; former_owners is sparse for vessels flagged in states with limited public registry disclosure, and we'd rather return an empty array than a confident lie. The alternative — presenting a clean record where the data doesn't support one — is exactly how customers end up chartering the wrong ship.

Disambiguating the transmitter from the hull

Given all of this, "MMSI lookup" turns out to be a small phrase covering a fairly large pile of work. When an MMSI comes in, the system has to decide which hull it currently maps to, and flag uncertainty when two hulls are broadcasting the same number. Then the registries have to be reconciled: flag state databases, classification societies, port state control records, and AIS feeds all carry partial and often contradictory views of the same ship. Somewhere in the pipeline they get merged with a defensible source priority — IMO GISIS, flag state registry, AIS static, last-seen timestamp as tiebreaker — rather than a coin flip.

And then there's the matter of vessels that are actively lying about where they are. AIS messages are unauthenticated; there is no cryptographic integrity on the protocol and there never has been, despite twenty years of industry conversation about it. A vessel can broadcast a false MMSI, a false position, or both. The most documented case is the Black Sea, where mass GNSS interference around the Crimean peninsula has placed dozens of vessels at false locations simultaneously — the signature of deliberate infrastructure-level spoofing rather than individual misconfiguration. The Persian Gulf and Chinese coastal waters show different patterns, more consistent with individual vessels concealing dark activity than fleet-wide displacement. The Eastern Mediterranean and the Baltic have joined the list since 2022.

The defense against this is unglamorous. A serious lookup flags physically impossible position transitions: a ship logged in Singapore on Tuesday cannot appear in the Black Sea on Wednesday, because the implied speed would be impossible for any displacement hull. Detection isn't a single threshold — it's a combination of implied speed (commonly set somewhere in the 30–60 knot range, depending on vessel class and operator), acceleration envelopes, and cross-checks against legitimate fast traffic like ferries and patrol craft. It's probabilistic. It catches most cases, occasionally flags a perfectly innocent fast ferry, and never gives you the satisfying yes-or-no answer you'd like.

The honest framing

The reason "MMSI lookup API" is a useful search query but a slightly misleading product description is that nobody actually wants an MMSI lookup. They want to know what ship they're looking at. They want to enrich a port call record. They want to check if the vessel showing up in their charter quote is the same one that ran aground off Suez last year under a different name.

The MMSI is the way in. It's the doorknob, not the room.

What sits behind it — if the API is doing its job — is a model of vessel identity that knows the difference between a transmitter and a hull, between a current name and a historical one, between an authoritative source and a noisy one. That model is the actual product. The nine-digit number is just the most convenient way for you to ask the question.

The ships out there, slowly tracing wakes across the North Atlantic, don't care what we call them. They wear names the way people wear coats — putting one on for a season, hanging another in the back of the closet, occasionally forgetting which one they showed up in. The MMSI is the label sewn into the collar of the coat the ship is wearing today. If you want to know who's inside, you have to look further in.

Top comments (0)