> ## Documentation Index
> Fetch the complete documentation index at: https://docs.vouch.expert/llms.txt
> Use this file to discover all available pages before exploring further.

# Quickstart

> Get started with Vouch in 5 minutes

## Get Your API Credentials

<Steps>
  <Step title="Sign up for Vouch">
    Create a free account at [vouch.expert](https://vouch.expert)
  </Step>

  <Step title="Create a project">
    Projects help you organize different applications and environments
  </Step>

  <Step title="Get your API keys">
    Each project comes with 4 API keys:

    * **Client Test** - For development in the browser
    * **Client Live** - For production in the browser
    * **Server Test** - For development on the server
    * **Server Live** - For production on the server
  </Step>
</Steps>

<Warning>
  Never use **Server keys** in client-side code - they can validate any email without domain restrictions!
</Warning>

## Installation

Choose your platform:

<Tabs>
  <Tab title="JavaScript/React">
    <CodeGroup>
      ```bash npm theme={null}
      npm install @vouch-in/js
      # or for React
      npm install @vouch-in/react
      ```

      ```bash yarn theme={null}
      yarn add @vouch-in/js
      # or for React
      yarn add @vouch-in/react
      ```

      ```bash pnpm theme={null}
      pnpm add @vouch-in/js
      # or for React
      pnpm add @vouch-in/react
      ```
    </CodeGroup>
  </Tab>

  <Tab title="Node.js">
    <CodeGroup>
      ```bash npm theme={null}
      npm install @vouch-in/node
      ```

      ```bash yarn theme={null}
      yarn add @vouch-in/node
      ```

      ```bash pnpm theme={null}
      pnpm add @vouch-in/node
      ```
    </CodeGroup>
  </Tab>

  <Tab title="Next.js">
    <CodeGroup>
      ```bash npm theme={null}
      npm install @vouch-in/next
      ```

      ```bash yarn theme={null}
      yarn add @vouch-in/next
      ```

      ```bash pnpm theme={null}
      pnpm add @vouch-in/next
      ```
    </CodeGroup>
  </Tab>

  <Tab title="iOS">
    Add to your `Package.swift`:

    ```swift theme={null}
    dependencies: [
        .package(url: "https://github.com/Vouch-IN/vouch-sdk-ios", from: "0.1.7")
    ]
    ```
  </Tab>

  <Tab title="Android">
    Add to your `build.gradle`:

    ```gradle theme={null}
    dependencies {
        implementation 'com.vouch:vouch-sdk:0.1.7'
    }
    ```
  </Tab>
</Tabs>

<Tip>
  **Mobile apps:** The iOS and Android SDKs automatically send an `Origin` header as `app://your.bundle.id`. Add `app://your.bundle.id` (e.g., `app://com.example.myapp`) to your project's allowed domains in the [dashboard](https://vouch.expert/dashboard).
</Tip>

## Basic Usage

<Tabs>
  <Tab title="JavaScript">
    ```javascript theme={null}
    import { Vouch } from '@vouch-in/js';

    // Initialize with your client key
    const vouch = new Vouch(
      'your-project-id',
      'your-client-api-key'
    );

    // Validate an email (includes automatic device fingerprinting)
    const result = await vouch.validate('user@example.com');

    // Check the recommendation
    if (result.recommendation === 'allow') {
      console.log('Email is valid!');
    } else {
      // Use the message field for a user-friendly error
      console.log(result.message); // e.g. "Please use a permanent email address, not a temporary one."
    }
    ```
  </Tab>

  <Tab title="React">
    ```jsx theme={null}
    import { VouchProvider, useValidateEmail } from '@vouch-in/react';
    import { useState } from 'react';

    function App() {
      return (
        <VouchProvider
          projectId="your-project-id"
          apiKey="your-client-api-key"
        >
          <SignupForm />
        </VouchProvider>
      );
    }

    function SignupForm() {
      const { validate, loading, data, error } = useValidateEmail();
      const [email, setEmail] = useState('');

      const handleSubmit = async (e) => {
        e.preventDefault();
        const result = await validate(email);

        if (result.recommendation === 'allow') {
          // Proceed with signup
          console.log('Email is valid!');
        }
      };

      return (
        <form onSubmit={handleSubmit}>
          <input
            type="email"
            value={email}
            onChange={(e) => setEmail(e.target.value)}
          />
          <button disabled={loading}>
            {loading ? 'Validating...' : 'Sign Up'}
          </button>

          {data && data.recommendation !== 'allow' && (
            <p>{data.message}</p>
          )}
          {error && <p>{error.message}</p>}
        </form>
      );
    }
    ```
  </Tab>

  <Tab title="Node.js">
    ```javascript theme={null}
    import { Vouch } from '@vouch-in/node';

    // Initialize with your server key
    const vouch = new Vouch(
      'your-project-id',
      'your-server-api-key'
    );

    // Validate an email (server-side)
    const result = await vouch.validate('user@example.com', {
      ip: request.ip,
      userAgent: request.headers['user-agent']
    });

    // Check the recommendation
    if (result.recommendation === 'allow') {
      // Create user account
      console.log('Email is valid!');
    } else {
      // Use the message field for a user-friendly error
      console.log(result.message); // e.g. "Please use a permanent email address, not a temporary one."
    }
    ```
  </Tab>

  <Tab title="Next.js (Server)">
    ```typescript theme={null}
    // app/api/validate/route.ts
    import { Vouch } from '@vouch-in/next';

    const vouch = new Vouch(
      process.env.VOUCH_PROJECT_ID!,
      process.env.VOUCH_SERVER_KEY!
    );

    export async function POST(request: Request) {
      const { email } = await request.json();

      const result = await vouch.validate(email, {
        ip: request.headers.get('x-forwarded-for') || undefined,
        userAgent: request.headers.get('user-agent') || undefined,
      });

      if (result.recommendation !== 'allow') {
        return Response.json({ error: result.message }, { status: 400 });
      }

      return Response.json({ success: true });
    }
    ```

    ```typescript theme={null}
    // app/signup/page.tsx (Client)
    'use client';

    import { VouchProvider, useValidateEmail } from '@vouch-in/next/client';

    export default function SignupPage() {
      return (
        <VouchProvider
          projectId={process.env.NEXT_PUBLIC_VOUCH_PROJECT_ID!}
          apiKey={process.env.NEXT_PUBLIC_VOUCH_CLIENT_KEY!}
        >
          <SignupForm />
        </VouchProvider>
      );
    }
    ```
  </Tab>

  <Tab title="iOS">
    ```swift theme={null}
    import VouchSDK

    let vouch = Vouch(
        projectId: "your-project-id",
        apiKey: "your-client-api-key"
    )

    Button("Sign Up") {
          Task{
            do {
                let result = try await vouch.validate(email)

                if let data = result.data {
                    switch data {
                    case .validation(let validationData):
                        if validationData.recommendation == .allow {
                            // Create account
                            print("Email is valid!")
                        } else {
                            // Example: check specific signals
                            if validationData.checks["syntax"]?.pass == false {
                                print("Invalid email format")
                            } else {
                                print("Blocked: \(validationData.recommendation.rawValue)")
                            }
                        }

                    case .error(let errorData):
                        print("Validation error: \(errorData.message)")
                    }
                } else {
                    print(result.error ?? "Email validation failed")
                }
            } catch {
                print("Validation failed: \(error.localizedDescription)")
            }
        }
    }
    ```
  </Tab>

  <Tab title="Android">
    ```kotlin theme={null}
    import expert.vouch.sdk.Vouch
    import kotlinx.coroutines.launch

    val vouch = Vouch(
        context = applicationContext,
        projectId = "your-project-id",
        apiKey = "your-client-api-key"
    )

    Button(onClick = {
        scope.launch {
            try {
                val result = vouch.validate(email)

                result.data?.let { data ->
                    when (data) {
                        is ValidationData.Validation -> {
                            val response = data.response

                            if (response.recommendation == "allow") {
                                // Create account
                                println("Email is valid!")
                            } else {
                                // Example: check specific signal
                                if (response.signals["syntax"]?.pass == false) {
                                    println("Invalid email format")
                                } else {
                                    println("Blocked: ${response.recommendation}")
                                }
                            }
                        }

                        is ValidationData.Error -> {
                            println("Validation error: ${data.response.message}")
                        }
                    }
                }

            } catch (e: Exception) {
                println("Validation failed: ${e.message}")
            }
        }
    }) {
        Text("Sign Up")
    }
    ```
  </Tab>
</Tabs>

## Understanding the Response

Every validation returns a response with:

```typescript theme={null}
{
  "checks": {
    "syntax": { "pass": true, "latency": 2 },
    "disposable": { "pass": true, "latency": 15 },
    "mx": { "pass": true, "latency": 45 }
  },
  "message": null,
  "metadata": {
    "fingerprintHash": "abc123...",
    "previousSignups": 0,
    "totalLatency": 182
  },
  "recommendation": "allow",
  "signals": ["new_device", "valid_email"]
}
```

### Key Fields

* **`recommendation`** - Overall recommendation: `allow`, `block`, or `flag`
* **`message`** - Human-friendly error message when recommendation is `flag` or `block` (e.g. "Please use a permanent email address, not a temporary one."). `null` when `allow`.
* **`checks`** - Individual validation results (syntax, disposable, mx, etc.)
* **`metadata`** - Device fingerprint and signup history
* **`signals`** - Array of signal identifiers detected

### Handling Results

Use the `message` field for quick user-facing errors, or check individual validations for custom logic:

```javascript theme={null}
const result = await vouch.validate(email);

// Option 1: Use the message field for a user-friendly error
if (result.recommendation === 'allow') {
  // Email is valid, proceed
} else {
  // Show the human-friendly error message
  console.log(result.message); // e.g. "Please use a permanent email address, not a temporary one."
}

// Option 2: Check individual validations for custom logic
const { checks, metadata } = result;

if (!checks.syntax?.pass) {
  // Invalid email format
}

if (!checks.disposable?.pass) {
  // Disposable email detected
}

if (metadata.previousSignups > 5) {
  // Multiple signups from this device
}
```

## Client vs Server Keys

<CardGroup cols={2}>
  <Card title="Client Keys" icon="browser">
    **Use in browsers/mobile apps**

    * Restricted to allowed domains
    * Lower rate limits (1,000/hour)
    * Safe to expose publicly
    * Includes device fingerprinting
    * Mobile apps: add `app://your.bundle.id` to allowed domains
  </Card>

  <Card title="Server Keys" icon="server">
    **Use on your backend**

    * No domain restrictions
    * Higher rate limits (5,000/hour)
    * Must be kept secret
    * Can override IP/User-Agent
  </Card>
</CardGroup>

<Warning>
  Server keys are blocked from browsers. If you try to use a server key in client-side code, you'll get a 401 error.
</Warning>

## Next Steps

<CardGroup cols={2}>
  <Card title="Explore Validation Types" icon="shield" href="/validation/overview">
    Deep dive into each validation check
  </Card>

  <Card title="API Reference" icon="code" href="/api-reference/validate">
    Complete API documentation
  </Card>

  <Card title="Best Practices" icon="star" href="/guides/best-practices">
    Production deployment tips
  </Card>
</CardGroup>
