# Multi-account and account sharing abuse evaluation (v2)

Get risk evaluations for account registration and login events using the v2 Account Evaluations API.

The Account Evaluations API provides risk intelligence for your registration and login flows to detect multi-accounting patterns and suspicious account sharing:

- **No payment collection required**: Evaluate risk during registration and at login, before collecting any payment information.
- **Get risk scores earlier**: Apply decision signals earlier in your workflow to get risk scores sooner (login or registration) than you can from a payment. This can help you make informed decisions about allowing or blocking account access where service abuse is suspected.

### Multi-account abuse 

The `user_multi_accounting` signal identifies whether a single fraudulent actor is registering multiple accounts to abuse your service.

### Account sharing abuse 

The `user_account_sharing` signal identifies whether a single user account is being used simultaneously in multiple locations.

### Request to join the preview for multi-account and account sharing abuse signals.

Enter your email to request access.

```bash
curl https://docs.stripe.com/preview/register \
  -X POST \
  -H "Content-Type: application/json" \
  -H "Referer: https://docs.stripe.com/radar/multi-account-and-account-sharing-abuse-v2" \
  -d '{"email": "EMAIL", "preview": "radar_customer_evaluation_preview"}'
```

## Account evaluation lifecycle

To request an account evaluation to detect abuse:

1. On the client side, use [Stripe.js](https://docs.stripe.com/sdks/stripejs-react.md) to create a [Radar Session](https://docs.stripe.com/radar/radar-session.md) that captures device metadata, then send the session token to your server.
2. [Create a customer](https://docs.stripe.com/api/customers/create.md) (or use an existing `Customer` object). Reference this customer as `account_details.customer` in the evaluation request. If you can’t create one at registration time, see [Entityless evaluations](https://docs.stripe.com/radar/multi-account-and-account-sharing-abuse-v2.md#entityless-evaluations).
3. Request an `AccountEvaluation` when customers register or log in.
4. After the customer registers or logs in, report the outcome to Stripe to improve future evaluations.

The following diagram shows the high-level interactions between you (the business), Stripe, and your end customer at registration time.

A diagram showing the Account Evaluations API sequence of interactions for a registration flow. (See full diagram at https://docs.stripe.com/radar/multi-account-and-account-sharing-abuse-v2)

```text
[Customer] -- Initiates registration --> [Client app]
[Client app] -- Create Radar Session --> [Stripe API]
[Stripe API] -- radar_session token --> [Client app]
[Client app] -- Registration data + radar_session --> [Business backend]
[Business backend] -- Create Customer --> [Stripe API]
[Stripe API] -- Customer object --> [Business backend]
[Business backend] -- Request account evaluation --> [Stripe API]
[Stripe API] -- Evaluated signals (score + risk_level) --> [Business backend]
[Business backend] -- Use scores to decide --> [Business backend]
[Business backend] -- Allow/block registration --> [Client app]
[Business backend] -- Report decision --> [Stripe API]
```

## Create a Radar Session

Before requesting an account evaluation, you must capture device metadata from the client using Stripe.js. Pass the [Radar Session](https://docs.stripe.com/radar/radar-session.md) token from the response to your server to use it in the account evaluation request.

> Radar Sessions expire shortly after creation. Create the session as close to submitting the evaluation as possible to avoid a timeout.

### If session creation fails or times out 

If `stripe.createRadarSession()` fails or times out (for example, due to an ad blocker or network error), you can still request an evaluation by passing the user’s IP address using `client_details.data` instead of `client_details.radar_session`. You can also include `user_agent` and `referrer` to improve signal quality. For `referrer`, use `document.referrer` from the client if available.

```curl
curl -X POST https://api.stripe.com/v2/signals/account_evaluations \
  -H "Authorization: Bearer <<YOUR_SECRET_KEY>>" \
  -H "Stripe-Version: 2026-07-29.preview" \
  --json '{
    "account_details": {
        "customer": "cus_****"
    },
    "requested_signals": [
        "user_multi_accounting"
    ],
    "account_activity_details": {
        "data": {
            "type": "registration_attempt",
            "registration_attempt": {
                "client_details": {
                    "data": {
                        "ip": "203.0.113.42",
                        "user_agent": "Mozilla/5.0 ...",
                        "referrer": "https://example.com/signup"
                    }
                }
            }
        }
    }
  }'
```

An IP-only evaluation produces less accurate scores than a full Radar Session because it lacks device-level signals. When possible, resolve the root cause of session creation failures rather than relying on this fallback long-term. See [Radar Session troubleshooting](https://docs.stripe.com/radar/radar-session.md) for more information.

## Create an AccountEvaluation

After you create a [Radar Session](https://docs.stripe.com/radar/radar-session.md) to capture device metadata, request an [AccountEvaluation](https://docs.stripe.com/api/v2/signals/account-evaluations/create.md) to get risk signals from Stripe. Include the registration or login activity in the same request through `account_activity_details`, so Stripe can evaluate the signal and record the activity in a single call.

### Registration flow

Request the `user_multi_accounting` signal to evaluate new user registrations. Reference an existing `Customer` in `account_details.customer`. To ensure accurate fraud detection, preserve the customer ID to use in future payment requests.

```curl
curl -X POST https://api.stripe.com/v2/signals/account_evaluations \
  -H "Authorization: Bearer <<YOUR_SECRET_KEY>>" \
  -H "Stripe-Version: 2026-07-29.preview" \
  --json '{
    "account_details": {
        "customer": "cus_****"
    },
    "requested_signals": [
        "user_multi_accounting"
    ],
    "account_activity_details": {
        "data": {
            "type": "registration_attempt",
            "registration_attempt": {
                "client_details": {
                    "radar_session": "rse_****"
                }
            }
        }
    }
  }'
```

### Login flow

Request the `user_account_sharing` signal to evaluate user login attempts and detect account sharing patterns. Use the same customer ID that you created during registration.

```curl
curl -X POST https://api.stripe.com/v2/signals/account_evaluations \
  -H "Authorization: Bearer <<YOUR_SECRET_KEY>>" \
  -H "Stripe-Version: 2026-07-29.preview" \
  --json '{
    "account_details": {
        "customer": "cus_****"
    },
    "requested_signals": [
        "user_account_sharing"
    ],
    "account_activity_details": {
        "data": {
            "type": "login_attempt",
            "login_attempt": {
                "client_details": {
                    "radar_session": "rse_****"
                }
            }
        }
    }
  }'
```

> `user_multi_accounting` and `user_account_sharing` evaluate synchronously. The score is returned inline in `evaluated_signals` on the create response, with an empty `pending_signals` array. You don’t need to wait for a webhook event or poll the [AccountEvaluation](https://docs.stripe.com/api/v2/signals/account-evaluations/retrieve.md) before acting.

### Risk signals

Stripe returns risk signals in the response based on the evaluation type. Use these signals to make informed decisions about allowing or blocking the action.

| Evaluation type | Signal requested | Description |
| --- | --- | --- |
| `registration_attempt` | `user_multi_accounting` | Risk that the same end customer is registering multiple times |
| `login_attempt` | `user_account_sharing` | Risk that the same account is being used from multiple locations simultaneously |

### Score interpretation

Each signal returns a `score` from 0 to 100 and a corresponding `risk_level` that categorizes the score into a qualitative band. Use the `risk_level` to make quick decisions, or use the raw `score` for fine-grained control.

| Risk level | Score range | Description |
| --- | --- | --- |
| `highest` | 75–100 | Indicates a high risk of abuse. Consider blocking or requiring additional verification. |
| `elevated` | 65–74 | Indicates an elevated risk of abuse. Consider applying additional friction or review. |
| `normal` | 0–64 | Indicates typical risk. No additional action recommended. |

### Entityless evaluations 

If you can’t create a `Customer` or `Account` object for your architecture at registration time, pass `account_details.data.contact_email` instead of `account_details.customer` or `account_details.account`.

> Use a `Customer` or `Account` object whenever possible. It helps Stripe make more accurate risk assessments over time.

Because Stripe has no ID to look up prior activity for an entityless request, you must include the current registration or login attempt (with its `client_details`) in the same request through `account_activity_details`. Stripe can’t fall back to a previously reported activity like it can for a `Customer` or `Account`.

#### Example of an entityless registration flow

```curl
curl -X POST https://api.stripe.com/v2/signals/account_evaluations \
  -H "Authorization: Bearer <<YOUR_SECRET_KEY>>" \
  -H "Stripe-Version: 2026-07-29.preview" \
  --json '{
    "account_details": {
        "data": {
            "contact_email": "jenny.rosen@example.com"
        }
    },
    "requested_signals": [
        "user_multi_accounting"
    ],
    "account_activity_details": {
        "data": {
            "type": "registration_attempt",
            "registration_attempt": {
                "client_details": {
                    "radar_session": "rse_****"
                }
            }
        }
    }
  }'
```

## Report outcome

After you act on an account evaluation, report the outcome back to Stripe so Stripe can improve future evaluations for your account.

Create an `AccountActivity` with a `*_decision` type, referencing the `AccountEvaluation` you’re reporting on:

```curl
curl -X POST https://api.stripe.com/v2/signals/account_activity \
  -H "Authorization: Bearer <<YOUR_SECRET_KEY>>" \
  -H "Stripe-Version: 2026-07-29.preview" \
  --json '{
    "account_details": {
        "customer": "cus_****"
    },
    "account_evaluation": "acctevl_****",
    "type": "registration_decision",
    "registration_decision": {
        "status": "blocked"
    }
  }'
```

### Status values

| Status | When to use | Example |
| --- | --- | --- |
| `allowed` | You allowed the registration or login to proceed without restrictions. | A user registers and receives full access to your platform. |
| `restricted` | You allowed the registration or login to proceed, but applied restrictions based on the risk signal. | A new account gains access but receives fewer promotional credits, is placed on a probationary tier, or has limited access to certain features until additional verification. |
| `blocked` | You blocked the registration or login entirely. The user wasn’t granted access. | A registration attempt is rejected outright, and the user can’t create an account. |

Reporting outcomes trains Stripe’s models to better distinguish abusive from legitimate behavior on your platform.

## Test your integration

Use a `Customer` with one of the following test email addresses in your account evaluation requests to simulate specific risk scores in test mode:

| Email address | Risk level | Score |
| --- | --- | --- |
| `high_scoring_email@example.com` | `highest` | 80 |
| `elevated_scoring_email@example.com` | `elevated` | 65 |
| `normal_scoring_email@example.com` | `normal` | 20 |

## Reuse the customer for payments

When creating payments, you must use the same customer ID that you used for the account evaluation. This connects registration, login, and payment activity for the same customer, which improves risk assessment accuracy.

```curl
curl https://api.stripe.com/v1/payment_intents \
  -u "<<YOUR_SECRET_KEY>>:" \
  -d amount=1000 \
  -d currency=usd \
  --data-urlencode "customer=cus_****" \
  --data-urlencode "payment_method=pm_****" \
  -d confirm=true
```

> The `customer` parameter at the time of payment must match the customer ID used when creating the `AccountEvaluation`.
