How fingerprints are made
In an engagement space each side counts its own records: leads, meetings, opportunities. To line the two sides up, each record is turned into a fingerprint on the side's own device or by the side's own AI, and only the fingerprint is sent to osmarks.
The key stays with the two sides
Every engagement has its own secret key. It is made in the browser of whoever opens the new space first and is passed only to the other side's devices and to each side's own new devices, encrypted for each device, so osmarks relays it without being able to read it. A fingerprint is HMAC-SHA-256(key, "osmarks/v2|" + identifier) in lowercase hex.
Because osmarks doesn't have the key, it can't recompute a fingerprint from a guessed address, so it can't tell who is behind one. The two sides, who both hold the key, can. Fingerprints are therefore pseudonymised data, not anonymous data, and they are only ever compared within one engagement.
Limits, honestly: the page that makes fingerprints in your browser is served by osmarks, as with any web app. The code is the same for everyone and public at /spaces/fp.mjs, and the space page shows how many of each side's devices hold the key, so a device you don't recognise would show. If you don't want to rely on the browser, your AI or your developer can make fingerprints with their own code from these rules.
Identifiers
- Email (
email:): trimmed, lower case, Unicode NFC. For gmail.com and googlemail.com only, dots and anything after "+" are removed from the part before "@" and the domain becomes gmail.com. Work addresses are kept as they are, because their providers treat dots and plus signs differently. - Company (
domain:): the registrable domain of an email address, a website or a bare domain, from the ICANN section of the Public Suffix List: mail.eu.acme.co.uk is acme.co.uk. International names in punycode. Free email domains (gmail.com, outlook.com and others) give no company. - Phone (
phone:, only if both sides turn it on): E.164, a + and 8 to 15 digits. Only numbers written with their country code (+ or 00) count; "(0)" is dropped. - LinkedIn (
linkedin:, only if both sides turn it on):linkedin.com/in/and the profile name, decoded and in lower case. People can change it, so it is a helper, not a main identifier.
A person can have several identifiers on one line (separated by commas, semicolons, tabs or spaces); two records that share any fingerprint are the same record. A meeting is a person and the date it took place: meeting|email:ana@acme.com|2026-10-14. The check value that tells a right key from a wrong one is HMAC-SHA-256(key, "osmarks/v2|key-check").
Test vectors
With the key 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f, phone turned on.
| Kind | Line | Identifiers and fingerprints |
|---|---|---|
| person | Ana.Perez+promo@GoogleMail.com | email:anaperez@gmail.com2d33794370d18a9e3b90383aed9f95e1a7a7ddeeed575bf458d8de1ac1061cf3 |
| person | j.smith@Acme.co.uk, +44 (0)20 7946 0000 | email:j.smith@acme.co.uk92dec7ee79003f834425948d397b9f4796c965843ff6c36b4d91ad40f42dd371 phone:+4420794600002ad5c085142039ecc81120a1ba521d64b6eabdde2d654b3e6725fa74d19933c3 |
| company | https://www.eu.acme.co.uk/team | domain:acme.co.uk437b38300b08d9cc3c5174fcc039ca674bb48d98f78148d9d553b749f8afd8f3 |
| company | bob@gmail.com | no identifier (not counted) |
| meeting | ana@acme.com 2026-10-14 | meeting|email:ana@acme.com|2026-10-14409d25d4fc7783afc703b8e911237039d7636becfaa7cb1ceb10134fccc9550d |
Key check for this key: 6adefd14f4a07ffafc9c8a439374bc81539dfddfcc2cdc13d0c991c62b9448d2
What osmarks keeps
Counts, fingerprints and the key's check value. It shows the two sides how many records match and how many are on one side only, and never which ones. Wording note: we say pseudonymised, never anonymous.