Multi-accounting and account sharing look like the same problem and are not. Multi-accounting is one device wearing many accounts: trial abuse, referral farming, bonus hunting, and the person on the other end was never going to pay you. Sharing is the mirror image — one account worn by many devices — and almost everyone you detect is a paying customer. That difference should decide everything about how you respond, and it usually does not.

The other reason to care: sharing and account takeover produce the same first observation. A new device on an existing account is either a partner's laptop, a password posted in a group chat, or someone who bought the credentials. Telling those apart is the whole exercise.

Why counting IPs does not work

The first instinct is to count distinct IPs per account and alert above some number. It fails in both directions, badly enough that the metric is worse than nothing.

False positives. Mobile carriers put tens of thousands of subscribers behind carrier-grade NAT, and hand out a different address on every reconnection. One commuter checking your app on a train produces a dozen IPs before lunch. Add an office, a home connection, a coffee shop and a corporate VPN and an ordinary week for one person looks like a small botnet.

False negatives. Anyone deliberately sharing a credential — especially anyone reselling one — already knows about IP checks. A shared account routed through one VPN exit shows a single stable address for every user of it, which reads as the tidiest account on your books.

So the signal is not how many networks. It is how many devices, and what those devices do.

Devices, not addresses

A verdict from /v1/evaluate carries a device block when the client token came from a real browser session:

{
  "decision": "allow",
  "risk_score": 0,
  "network": { "vpn": false, "proxy": false, "residential": true },
  "device": {
    "visitor_id": "…",       // stable across sessions
    "times_seen": 14,
    "returning": true,
    "first_seen": "2026-06-30T09:12:44.000Z",
    "linked_accounts": 1,
    "multi_account": false
  }
}

Three of those fields are the raw material for sharing detection. visitor_id is a stable identifier for that browser, so it survives logout, a cleared cookie and a new session — which is what makes "devices per account" countable at all. first_seen and times_seen separate a device that has been on the account for months from one that appeared this morning.

One caveat worth stating plainly, because it is the difference between a working integration and a confusing afternoon: the device block only exists when a real browser produced the token. The sandbox tokens (test_clean, test_vpn, and the rest) return the decision and the network block with no device object at all, because there was no browser. Wire the collector into the page before you go looking for visitor_id in the response.

The API answers the other direction

linked_accounts counts how many of your accounts have been seen on this device, which is the multi-accounting question. Sharing is the transpose: how many devices have been seen on this account. That one you keep yourself, because it is a fact about your users and it belongs in your database.

It is one table:

CREATE TABLE account_devices (
  account_id  TEXT NOT NULL,
  visitor_id  TEXT NOT NULL,
  country     TEXT,
  first_seen  TIMESTAMPTZ NOT NULL DEFAULT now(),
  last_seen   TIMESTAMPTZ NOT NULL DEFAULT now(),
  PRIMARY KEY (account_id, visitor_id)
);

Upsert it on every login with the verdict you already have, then ask the question:

-- Active devices per account over a rolling 30 days.
SELECT account_id,
       COUNT(*)                AS devices,
       COUNT(DISTINCT country) AS countries,
       COUNT(*) FILTER (WHERE first_seen > now() - interval '7 days')
                               AS new_this_week
FROM account_devices
WHERE last_seen > now() - interval '30 days'
GROUP BY account_id
HAVING COUNT(*) >= 6
ORDER BY devices DESC;

Note the rolling window. A lifetime device count only measures how long someone has been a customer — a loyal five-year user has replaced two phones and a laptop and will out-rank an actively shared account every time.

The same 90-day ceiling applies on our side: the device-to-account links behind linked_accounts are pruned at ninety days, so that number is a rolling window too, not a permanent record.

Separating a household from a resale

Six devices is not evidence. A family of four with phones, a tablet and a TV is six devices and is exactly the customer you want. Four patterns separate normal sharing from the kind that costs you money, and they are much more convincing together than apart.

Device churn. A household's device set is stable: the same six identifiers month after month, each with an old first_seen. A resold credential shows constant turnover — new devices every week, each seen a handful of times and never again. Churn is the strongest single tell, and it is why first_seen matters more than the raw count.

Geographic dispersion beyond travel. Not "two countries" — people travel, people live near borders, people work remotely. The tell is dispersion that cannot be reconciled with one human body: sessions in three countries on the same afternoon, or a pair of logins whose distance and interval imply a speed nobody achieves. Compute it as a rate, not a count.

Concurrency. Genuine sharing is usually sequential — a household takes turns. Simultaneous sustained use from several devices is the signature of a credential in circulation. We do not see your sessions, so this one is entirely yours to measure; it is also the cheapest, because you already log session start and end.

The account arrives hidden. Cross-reference the network block. A residential connection from the customer's own country carries no information either way. A credential being resold is often used through a VPN or a residential proxy by people who know the account is not theirs — so network.vpn or network.proxy on devices that are also new and geographically scattered is a much stronger combination than any of those alone.

Say that last one carefully, because it is where teams do real damage: a VPN on its own is not evidence of anything. Plenty of privacy-minded customers use one full time, which is why a plain VPN returns review rather than block. Treat it as one term in a sum, never as a trigger.

Sharing or takeover?

Before you act on a sharing signal, check whether you are actually looking at a compromise. The observation is identical; the correct response is not even close.

What tips it toward takeover rather than sharing: the new device appears and the old ones stop, rather than continuing alongside; the session changes the email, password or payout details within minutes of logging in; the verdict carries hard signals — automation_detected, antidetect_browser, emulator_detected — which are the tools of credential stuffing, not of a spouse borrowing a login.

Sharing is a pricing problem. Takeover is a security incident. Route them to different places, and when the evidence is genuinely ambiguous, treat it as the second one — a step-up on a shared account costs a customer thirty seconds, and a missed takeover costs considerably more. There is more on that path in account takeover prevention that holds up.

What to do about it, in order

The instinct is to block the extra devices. For a paying account that is the most expensive option on the list, and it lands on the customer rather than the person who shared the credential.

1. Measure before you enforce. Run the query for a few weeks and act on nothing. You will find that your intuition about the threshold was wrong — usually far too low — and you will find a small number of accounts with thirty devices that are worth looking at by hand.

2. Verify the new device, not the account. An email or push confirmation on a device that has never been seen is cheap, expected by users, and does double duty against takeover. It is the only intervention here that a legitimate customer thanks you for.

3. Cap concurrency instead of devices. "Two streams at once" or "three active sessions" is enforceable, explainable, and matches how people think a subscription works. "You may only ever own four devices" does not survive contact with a phone upgrade.

4. Sell the thing they are trying to do. An account with eight stable devices across two households is a family plan you have not offered them, and an account with eleven devices on one corporate domain is a seat expansion. The message that converts is an invitation, not a warning — and unlike a block, it moves revenue in the right direction.

5. Enforce only on the tail. Reserve refusal for the accounts where the evidence is not ambiguous: high churn, impossible geography, sustained concurrency, hard device signals. That is a small set, and keeping it small is the point.

Where you draw the line depends on what you sell. A B2B SaaS seat is a contractual matter and a conversation with the customer usually settles it. A consumer subscription is a churn calculation: the shared viewer often converts later, and an aggressive crackdown can cost more in cancellations than the sharing ever cost in revenue.

Measure it as a distribution

One number for "sharing" is useless; the shape of the distribution is where the decisions are.

  • Devices per active account at p50, p95 and p99, on a rolling thirty days. p50 tells you what normal is. The gap between p95 and p99 is where policy belongs.
  • Share of accounts whose device set turned over more than half in the last thirty days — the churn metric, and the one that actually correlates with resale.
  • Distinct countries per account per week, as a rate rather than a total.
  • Conversion on the upgrade nudge, split by device count. This is the number that tells you whether sharing is a leak or an underserved segment.
  • Cancellation rate among accounts you intervened on, against a holdout you left alone. Without the holdout you cannot tell recovered revenue from churn you caused.

The constraints worth knowing

Device linking here is per-customer and hash-only: your accounts are never linked against another customer's, and both the device key and the account id you pass are stored as opaque hashes rather than in the clear. Links older than ninety days are pruned. If you build the account-side table described above, that one is yours — put it in your privacy notice and give it a retention period, because a device history per user is exactly the kind of processing users are entitled to know about.

The short version

  • Sharing is the transpose of multi-accounting: many devices per account, and the account is usually paying you.
  • Counting IPs finds commuters and misses anyone behind a single VPN. Count devices.
  • The API gives you accounts-per-device; keep devices-per-account yourself, on a rolling window.
  • Churn in the device set, impossible geography, sustained concurrency and hidden networks separate a household from a resale. A VPN alone separates nothing.
  • Check for takeover first: same observation, completely different response.
  • Verify new devices, cap concurrency, sell the upgrade. Refuse only the unambiguous tail, and keep a holdout so you can tell whether the policy paid.
FAQ

Frequently Asked Questions

How do you detect account sharing without blocking real customers?

Count devices per account over a rolling window rather than IPs, then look at the pattern instead of the total. Six stable devices with old first-seen dates is a household; six devices that turned over in the last month, used from scattered locations, is a credential in circulation. Respond with a confirmation on the new device or a concurrency cap rather than a ban, and keep a holdout group so you can measure whether enforcement recovered more revenue than it churned.

Why is counting IP addresses a bad way to find shared accounts?

It is wrong in both directions. Mobile carriers rotate addresses behind carrier-grade NAT, so one commuter can produce a dozen IPs in a morning and look like a shared account. Meanwhile a credential deliberately shared through a single VPN exit shows one stable address for every user of it, which looks cleaner than your average legitimate customer.

What is the difference between account sharing and multi-accounting?

They are opposite directions of the same relationship. Multi-accounting is one device used across many accounts — trial abuse, referral farming, bonus hunting — and the API reports it directly as device.linked_accounts with a multi_account_device reason code. Sharing is one account used across many devices, which you count in your own database from the device visitor_id, and the people involved are usually paying customers rather than abusers.

How do I tell account sharing apart from account takeover?

Look at whether the old devices keep being used and at what the session does. Sharing adds devices alongside the existing ones and behaves normally; takeover typically replaces them and changes the email, password or payout details soon after login. Hard signals in the verdict — automation_detected, antidetect_browser, emulator_detected — point to credential stuffing rather than a borrowed password. When it is genuinely ambiguous, treat it as takeover: a step-up costs a real customer half a minute.

Count devices, not addresses

Maskbreak returns a stable device identifier, how long it has been around, and how many of your accounts it has touched. Free tier: 1,000 requests per hour, no card.

Try Maskbreak free →