stile
Getting Started

Quickstart

Get Stile integrated into your app in under 5 minutes.

Prerequisites

You need a stile account and a publishable key. Get both from the dashboard.

1. Add the widget

Include the stile widget on your page. It's a standard web component — no build step required.

<script src="https://cdn.stile.dev/v1/stile.js"></script>
npm install @stile/widget

2. Drop in the button

Add the <stile-button> to your page with your publishable key. Point it at your email input and it handles the rest — session creation, the verification modal, and result callbacks.

Checkout.tsx
export function Checkout() {
  const handleVerified = (e: CustomEvent) => {
    console.log("Verified!", e.detail);
    // redirect, unlock content, etc.
  };

  return (
    <div>
      <input id="email" type="email" placeholder="you@example.com" />
      <stile-button
        publishable-key="pk_test_..."
        email-selector="#email"
        ref={(el) => el?.addEventListener("stile:verified", handleVerified)}
      />
    </div>
  );
}
Checkout.vue
<script setup>
function onVerified(e) {
  console.log("Verified!", e.detail);
}
</script>

<template>
  <input id="email" type="email" placeholder="you@example.com" />
  <stile-button
    publishable-key="pk_test_..."
    email-selector="#email"
    @stile:verified="onVerified"
  />
</template>
Checkout.svelte
<script>
  function onVerified(e) {
    console.log("Verified!", e.detail);
  }
</script>

<input id="email" type="email" placeholder="you@example.com" />
<stile-button
  publishable-key="pk_test_..."
  email-selector="#email"
  on:stile:verified={onVerified}
/>
checkout.html
<script src="https://cdn.stile.dev/v1/stile.js"></script>

<input id="email" type="email" placeholder="you@example.com" />
<stile-button
  publishable-key="pk_test_..."
  email-selector="#email"
></stile-button>

<script>
  document.querySelector("stile-button")
    .addEventListener("stile:verified", (e) => {
      console.log("Verified!", e.detail);
    });
</script>
verify.ts
import { verify } from "@stile/widget";

// One-call verification — opens a modal, handles the entire flow
const result = await verify({
  publishableKey: "pk_test_...",
  email: "user@example.com",
});

console.log("Verified!", result.sessionId);

That's it for the frontend. The widget handles session creation, the verification modal, QR codes, polling, and status updates automatically using your publishable key.

3. Know when someone verifies

After a user completes verification, you need to know about it so you can grant access, update your database, or unlock content.

stile notifies your server automatically using a webhook — a URL on your server that Stile calls when something happens. Think of it like a notification: stile sends your server a secure message saying "this user just verified", and your server decides what to do next.

Set up your webhook

Step 1: Go to Webhooks in the dashboard and add your server's URL (e.g. https://yourapp.com/api/webhooks). You'll get a webhook secret — save this somewhere safe.

Step 2: Install the server-side SDK:

npm install @stile/node

Step 3: Create a route on your server to receive the webhook:

app/api/webhooks/route.ts
import Stile from "@stile/node";

// Your secret API key (from the dashboard — keep this on your server only)
const stile = new Stile(process.env.STILE_API_KEY!);

export async function POST(req: Request) {
  // First, verify the message is really from stile (not spoofed)
  let event;
  try {
    event = await stile.webhooks.fromRequest(
      req,
      process.env.WEBHOOK_SECRET!, // the webhook secret from step 1
    );
  } catch (err) {
    return new Response("Invalid signature", { status: 400 });
  }

  // The event is verified — now handle it
  if (event.type === "verification_session.verified") {
    const session = event.data;
    // Update your database, grant access, etc.
    // await db.users.update({
    //   where: { id: session.client_reference_id },
    //   data: { verified: true },
    // });
  }

  return Response.json({ received: true });
}

That's it. Every time a user verifies on your site, Stile will call this URL and your server can act on it.

Two different keys

Your publishable key (pk_test_ / pk_live_) is used in the frontend widget and is safe to expose in your HTML. Your secret API key (vk_test_ / vk_live_) should only ever be used on your server — never in frontend code.

For more details on key types, rate limits, and key rotation, see Authentication.

Next steps

On this page