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/widget2. 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.
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>
);
}<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><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}
/><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>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/nodeStep 3: Create a route on your server to receive the webhook:
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
- Widget SDK reference — all attributes, events, and the JavaScript API
- Node.js SDK reference — full server-side API documentation
- Webhooks guide — retry behavior, signature verification, and local testing
- Verification Sessions API — manual session management for advanced use cases