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

# Quickstart

> Add Foil bot detection in 5 minutes. Load the browser client, request a sealed session handoff, verify it on your backend, and apply policy by verdict.

<Info>
  **Before you start**:

  * Import `t.js` from `https://cdn.usefoil.com`.
  * Use a publishable key (`pk_*`) in the browser and a secret key (`sk_*`) on your backend.
  * Keep the secret key server-side only.
  * The browser never receives Foil verdicts, scores, or visitor IDs.
</Info>

## 1. Install the server SDK

<CodeGroup>
  ```bash Node.js theme={"dark"}
  npm install @abxy/foil-server
  ```

  ```bash Python theme={"dark"}
  pip install foil-server
  ```

  ```bash Go theme={"dark"}
  go get github.com/abxy-labs/foil-server-go
  ```

  ```bash Ruby theme={"dark"}
  gem install foil-server
  ```

  ```bash PHP theme={"dark"}
  composer require abxy/foil-server
  ```
</CodeGroup>

## 2. Load the browser client

Start the client as early as possible on your page. Keep the returned promise for later use.

```html theme={"dark"}
<script type="module">
  const foilPromise = import("https://cdn.usefoil.com/t.js")
    .then((Foil) =>
      Foil.start({
        publishableKey: "pk_live_your_publishable_key",
      }),
    );

  async function setupFoil() {
    const foil = await foilPromise;
    foil.onError((error) => {
      console.error("Foil error", error.code, error.message);
    });

    // Optional: resolve early if you want fingerprinting ready before the action
    void foil.waitForFingerprint().catch(console.error);
  }

  setupFoil().catch(console.error);
</script>
```

## 3. Get a session at action time

Right before signup, login, checkout, or another sensitive action, request a sealed handoff and send it to your backend.

```html theme={"dark"}
<script type="module">
  const foil = await foilPromise;

  async function submitSignup(formData) {
    const { sessionId, sealedToken } = await foil.getSession();

    const response = await fetch("/api/signup", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({
        ...formData,
        foil: { sessionId, sealedToken },
      }),
    });

    return response.json();
  }
</script>
```

## 4. Verify on your backend

Verify the sealed token with your secret key. This is a local operation — no network call to Foil.

<CodeGroup>
  ```javascript Node.js theme={"dark"}
  const { safeVerifyFoilToken } = require("@abxy/foil-server");

  app.post("/api/signup", async (req, res) => {
    const result = safeVerifyFoilToken(
      req.body.foil.sealedToken,
      process.env.FOIL_SECRET_KEY,
    );

    if (!result.ok || result.data.decision.verdict === "bot") {
      return res.status(403).json({ error: "Blocked" });
    }

    // Proceed with signup
    createAccount(req.body);
    res.json({ success: true });
  });
  ```

  ```python Python theme={"dark"}
  from foil_server import safe_verify_foil_token
  import os

  @app.post("/api/signup")
  def signup(request):
      result = safe_verify_foil_token(
          request.json["foil"]["sealedToken"],
          os.environ["FOIL_SECRET_KEY"],
      )

      if not result.ok or result.data.decision.verdict == "bot":
          return {"error": "Blocked"}, 403

      create_account(request.json)
      return {"success": True}
  ```

  ```go Go theme={"dark"}
  import foil "github.com/abxy-labs/foil-server-go"

  func signupHandler(w http.ResponseWriter, r *http.Request) {
      var body SignupRequest
      json.NewDecoder(r.Body).Decode(&body)

      result := foil.SafeVerifyFoilToken(
          body.Foil.SealedToken,
          os.Getenv("FOIL_SECRET_KEY"),
      )
      if !result.OK || result.Data.Decision.Verdict == "bot" {
          http.Error(w, "Blocked", 403)
          return
      }

      createAccount(body)
      json.NewEncoder(w).Encode(map[string]bool{"success": true})
  }
  ```

  ```ruby Ruby theme={"dark"}
  require "foil/server"

  post "/api/signup" do
    body = JSON.parse(request.body.read)
    result = Foil::Server::SealedToken.safe_verify_foil_token(
      body.dig("foil", "sealedToken"),
      ENV.fetch("FOIL_SECRET_KEY"),
    )

    if !result[:ok] || result[:data][:decision][:verdict] == "bot"
      halt 403, { error: "Blocked" }.to_json
    end

    create_account(body)
    { success: true }.to_json
  end
  ```

  ```php PHP theme={"dark"}
  use Foil\Server\SealedToken;

  $body = json_decode(file_get_contents("php://input"), true);
  $result = SealedToken::safeVerify(
      $body["foil"]["sealedToken"],
      getenv("FOIL_SECRET_KEY"),
  );

  if (!$result->ok || $result->data->decision["verdict"] === "bot") {
      http_response_code(403);
      echo json_encode(["error" => "Blocked"]);
      exit;
  }

  createAccount($body);
  echo json_encode(["success" => true]);
  ```

  ```bash cURL theme={"dark"}
  # Alternatively, fetch the session from the API instead of verifying locally:
  curl https://api.usefoil.com/v1/sessions/sid_... \
    -H "Authorization: Bearer sk_live_..."
  ```
</CodeGroup>

## 5. Apply policy

Use the verdict to decide what to do:

| Verdict        | Action                                  |
| -------------- | --------------------------------------- |
| `human`        | Allow the request                       |
| `inconclusive` | Challenge (CAPTCHA, email verification) |
| `bot`          | Block or rate-limit                     |

Start in **report-only mode** (log verdicts without blocking) to understand your traffic before enforcing.

## What's next

<CardGroup cols={2}>
  <Card title="Browser SDK" icon="code" href="/browser-sdk">
    Full SDK API reference
  </Card>

  <Card title="Server verification" icon="shield-check" href="/server-verification">
    Advanced verification patterns
  </Card>

  <Card title="Testing" icon="flask-conical" href="/testing">
    Test your integration with bot traffic
  </Card>

  <Card title="Going to production" icon="rocket" href="/going-to-production">
    Rollout checklist and monitoring
  </Card>
</CardGroup>
