A row carries registry_number (SIREN), establishment_number (SIRET), vat_number,
name, postal_code, city, address and an optional ref, and nothing else: a column
under any other name, siren for instance, makes its row invalid, so rename your columns
before sending. A valid identifier is looked up exactly and the rest of the row is not
read. A name is matched, then placed by postal_code, city, or the postal code inside
address; any establishment there counts, open or closed, so a company that has moved is
still found. A name is matched only when one of its company's establishments is in that
postal code or city. Without a location, or only in the right département, it comes back
ambiguous with its candidates, however exact; outside any département the company has
had an establishment in, not_found. A ceased company is matched, with
legal_entity.status set to ceased.
Every row has a confidence between 0 and 1: 1 on an identifier match, the company's on a
name match, the best candidate's on an ambiguous row, 0 on not_found and invalid. A
name row is matched when its best candidate reaches 0.8 and leads the next company by at
least 0.15: candidates at 0.95 and 0.8 are a match on the first, candidates at 0.9 and 0.8
are ambiguous. Otherwise the row is ambiguous, with up to three candidates at 0.5 or
above, each with its own confidence, or not_found when none reaches 0.5: below that
floor there is no guess.
Those thresholds were measured, in November 2026, on 399 rows sampled from the French
registry and made deliberately messy: typos, legal forms in the name, trade names, former
names, moved head offices, homonyms, ceased companies, identifiers, and 74 rows that must
match nothing. Each name row's expected company was the only one bearing that name at that
postal code or city. On that set every matched row was the right company: 204 of 204 name
rows, and every identifier row, SIRETs of closed establishments included. Every row that
had to be refused was refused. 72.9 % of the name rows naming a real company were matched
outright; the rest came back ambiguous or not_found. By kind of row: a name with a
postal code or an address, a legal form added to the name, a trade name, a moved head
office or a ceased company, 88 % to 97 %; a name other companies bear in other cities,
83 %; a name with one letter wrong, 50 %; a former name, 4 %, because only current names
are searched. A name with no location, or
placed only in the right département, is not matched even though matching it would raise
that rate, so send a postal code or city with every name.
A trade name is matched on the establishment that bears it at the postal code or city
given, and establishment_number names that establishment: an open one before a closed
one, so a closed establishment is named only when the company has no open one there. This
holds for every name, so a row naming a franchisor can match a franchisee whose sign bears
that name, when the franchisor has no establishment at the place. A name with a slip in it,
a letter dropped, doubled, swapped or wrong, is read as misspelled only when no company's
name holds all of its words as written, and never when the name is under six characters.
Then, at the postal code or city given, the words the two names do not share are compared:
one letter off is allowed when they are under ten characters, two from ten, none when a
word is missing on one side, and the name scores 1 − edits / their length — "frures" for
"freres" scores 0.83 and can match, "martin" for "martel" is not a slip. Before such a row
is matched, the place is checked for another company as near the name: if there is one,
the row comes back ambiguous with it among the candidates; if the check runs out of
time, ambiguous with partial: true. A one-word name with a slip
takes the slowest search, and is the one most often answered partial.
What the measurement leaves out is the known failure: two companies bearing the same name
at the same place, because one's legal name is the other's trade name there or the right
one only has a closed establishment there. Resolve can match the wrong one at confidence
1.0. Such rows have two right answers, so the set excluded them, and its 100 % is not a
promise: a high confidence on a name row does not rule that case out. Nor does it cover a
name read as misspelled when another company at the same place is one or two letters from
it: the set holds no such row. Send an identifier
whenever you hold one, keep matched_on with each answer so you can tell later which rows
rest on a name, review ambiguous rows rather than taking the first candidate, and send a
partial row again rather than recording its answer.
results holds one entry per row sent, in the order sent; ref is echoed for your own
bookkeeping. A row that cannot be read is answered invalid in its place, with a
message saying why. The batch is refused with 400 invalid_request only when it is not a
batch: not JSON, no rows array, an empty one, or more than 500 rows.
A batch spends at most 10 seconds searching names. A row reached after that is not
searched: it comes back not_found with partial: true and a message saying so, and
belongs in your next batch. Identifier rows are answered whatever the budget. On a row that
was searched, partial: true means part of its search ran out of time, so its not_found
or ambiguous is not conclusive. One batch runs at a time per organization, and each
server answers one at a time, so even batches sent one after another can meet
429 concurrency_limited: retry after Retry-After seconds. For a file larger than one
batch, submit a file job instead: it takes the whole file, is never
refused for a running batch, and gives the file back with the matches appended as columns.
A batch is one call, however many rows it holds: on Free, one of the month's 1 000
lookups. Its rows are counted separately, on every plan, against the month's agent rows,
resolve and enrich together: 1 000 on Free, 25 000 on Pro, 250 000 on Scale, reset at the
start of each calendar month, UTC. Each row looked up — matched, ambiguous or
not_found — is one row, and a row repeated in the batch counts each time; invalid rows
and rows the budget left unsearched are not counted. The rows your unfinished file jobs
were admitted for and have not processed yet count as used. The allowance is checked before
the batch runs, so a batch admitted with rows left can take you past it by up to its own size,
and the next batch is refused with 402 quota_exceeded;
rate limits shows the rows header member to watch. Call it
from a server, with a secret key: a publishable
fk_pub key is refused, with 403 public_key_forbidden when it holds read. The key
travels as an Authorization header with the read scope;
authentication covers both.