---
title: Quick start
---

# Quick start

Rupt works the same on every platform: run an [evaluation](/docs/v3/concepts/evaluations) when the user takes an action, then confirm it on your server before you honor it. Here's the flow:

<!-- prettier-ignore-start -->
::MermaidDiagram
---
code: |
  sequenceDiagram
    actor U as User
    participant C as Client app
    participant S as Your server
    participant R as Rupt
    U->>C: Takes action (login / signup / access)
    C->>R: evaluate(action, user?, email?, phone?, metadata?)
    R-->>C: evaluation_id
    C->>S: Forward evaluation_id with the action request
    S->>R: GET /v3/evaluations/{evaluation_id}
    R-->>S: Evaluation (verdict, user, challenge, …)
    Note over S: Integrity check
    S-->>U: Honor or block the action
---
::
<!-- prettier-ignore-end -->

The **integrity check** is where your server confirms the evaluation matches what your client app sent and hasn't been tampered with.

## 1. Install the Rupt SDK

::ClientPlatform

#web

:::CodeTabs

#npm

```sh
npm install @ruptjs/client
```

#yarn

```sh
yarn add @ruptjs/client
```

#bun

```sh
bun add @ruptjs/client
```

#CDN

```html
<script src="https://cdn.rupt.dev/js/v3/rupt.js"></script>
```

:::

#ios

1. Download the SDK binary from <a href="/ios/sdk/RuptClient.xcframework.zip" target="_blank">RuptClient.xcframework.zip</a>.
2. Unzip and drag `RuptClient.xcframework` into your Xcode project.
3. Select **Copy items if needed** and click **Finish**.

#android

- Make sure `mavenCentral()` and `jitpack` are listed under `dependencyResolutionManagement` in `settings.gradle`.
- Add Rupt to your dependencies: `implementation("dev.rupt.android:rupt-android:4.0.0")`.

::

## 2. Run an evaluation (client-side)

Call `evaluate()` at the moment the user takes the action (e.g. right after they submit the login, sign up, or checkout).

::ClientPlatform

#web

```js
import Rupt from "@ruptjs/client";

const rupt = new Rupt({ clientId: "your_client_id" });

// Call rupt.evaluate.login / .signup / .access for the action you're protecting.
const response = await rupt.evaluate.login({
  user: "USER_ID",
  email: "EMAIL",
  phone: "PHONE",
  metadata: { key: "value" },
});
```

#ios

```swift
import Rupt

let rupt = Rupt(clientID: "your_client_id")

let response = try await rupt.evaluate(
  action: "login", // "login", "signup", or "access" (you can add more later)
  user: "USER_ID",
  email: "EMAIL",
  phone: "PHONE",
  metadata: ["key": "value"]
)
```

#android

```kotlin
import dev.rupt.Rupt

val rupt = Rupt(context, clientId = "your_client_id")

val response = rupt.evaluate(
  action = "login", // "login", "signup", or "access" (you can add more later)
  user = "USER_ID",
  email = "EMAIL",
  phone = "PHONE",
  metadata = mapOf("key" to "value"),
)
```

::

The response includes the `evaluation_id` that you need to send to your server in step 3.

## 3. Confirm the evaluation (server-side)

This step takes place on your server. Your server should take the `evaluation_id` from the client and get that evaluation details from Rupt.

```js
import RuptAPI from "@rupt/api";

const rupt = new RuptAPI("API_SECRET");
const evaluation = await rupt.evaluation.get(evaluation_id);

/** Alternatively: curl https://api.rupt.dev/v3/evaluations/$EVALUATION_ID \ -H "Authorization: Bearer $API_SECRET" **/
```

The response includes the [verdict](/docs/v3/concepts/verdicts), the [action](/docs/v3/concepts/actions), the user details Rupt received, the [policy](/docs/v3/concepts/policies) that matched, the [risks](/docs/v3/concepts/risks) detected, and the [challenge](/docs/v3/concepts/challenges) if one was issued, and more:

```json
{
  "id": "...",
  "action": "login",
  "verdict": "allow",
  "user": {
    "rupt_id": "...",
    "id": "USER_ID", // The user ID you provided to Rupt
    "email": "EMAIL", // The email you provided to Rupt
    "phone": "PHONE" // The phone you provided to Rupt
  },
  "metadata": { "key": "value" }, // The metadata you provided to Rupt
  "policy": { "id": "...", "name": "...", "action": { "type": "allow" } }, // The policy that matched
  "challenge": null, // The challenge details if one was issued
  "redirect": null, // The redirect URL if one was issued
  "risk_summary": [{ "category": "ato", "severity": "low" }], // The risks detected
  "createdAt": "...",
  "updatedAt": "..."
}
```

Confirm that the evaluation matches the action you expected, the user you expected, and the metadata you expected. **Treat any mismatch as a bad actor and block the action.**

## 4. Handle challenges

Out of the box you have no [policies](/docs/v3/concepts/policies), so every evaluation comes back `allow` and no challenge fires. That's expected; the steps above give you the plumbing and all the data you need to start writing policies that challenge, deny, or gate an action.

When a policy does issue a challenge, the evaluation comes back with a `redirect`. Sending the user through the hosted challenge and confirming they passed is a short round trip — the [Challenge flow](/docs/v3/challenge-flow) walks through it end to end.

Start with the two foundations; every other use case builds on them:

- **[Signup protection](/docs/v3/fundamentals/signup-protection)** — at signup the user is new and has no ID yet, so you store a little state to bind the pending signup to its challenge.
- **[Login protection](/docs/v3/fundamentals/login-protection)** — at login you don't store anything; you just hold off issuing the session until the challenge completes.

---

## Next steps

- [Concepts](/docs/v3/concepts/evaluations) — what evaluations, signals, checks, risks, verdicts, policies, and challenges actually mean.
- [Guides](/docs/v3/guides) — recommendations on specific fraud-prevention scenarios.
- [Proxy setup](/docs/v3/advanced/proxy-setup) — route Rupt traffic through your own domain to bypass adblockers and JS-domain blocking.
