Word?

Documentation

Add Word? to your site in one afternoon.

Quick start

bash
npm install @wordkey/sdk

Get your API key from the business portal, drop in the button, and verify tokens server-side. That's the whole integration.

The Word? button

jsx
import { WordKeyButton } from "@wordkey/sdk";

export function LoginPage() {
  return (
    <WordKeyButton
      apiKey="wk_live_xxxxxxxxxxxx"
      onSuccess={(user) => console.log("Authenticated:", user)}
      onError={(err) => console.error(err)}
    />
  );
}

Verify tokens server-side

typescript
import { WordKey } from "@wordkey/sdk/server";

const wk = new WordKey({ apiKey: process.env.WORDKEY_API_KEY });

export async function POST(req) {
  const { token } = await req.json();
  const user = await wk.verify(token);
  // user.id — permanent unique id
  // user.isNewUser — first authentication?
}

Other languages

Token verification is a single authenticated POST — call it from any stack.

python
import requests

def verify(token):
    r = requests.post(
        "https://app.wordkey.app/api/auth/token-verify",
        headers={"Authorization": f"Bearer {WORDKEY_API_KEY}"},
        json={"token": token},
    )
    r.raise_for_status()
    return r.json()  # { userId, isNewUser, authenticatedAt }
php
<?php
$ch = curl_init("https://app.wordkey.app/api/auth/token-verify");
curl_setopt_array($ch, [
  CURLOPT_POST => true,
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_HTTPHEADER => [
    "Authorization: Bearer " . getenv("WORDKEY_API_KEY"),
    "Content-Type: application/json",
  ],
  CURLOPT_POSTFIELDS => json_encode(["token" => $token]),
]);
$user = json_decode(curl_exec($ch), true);
ruby
require "net/http"
require "json"

uri = URI("https://app.wordkey.app/api/auth/token-verify")
req = Net::HTTP::Post.new(uri, {
  "Authorization" => "Bearer #{ENV['WORDKEY_API_KEY']}",
  "Content-Type" => "application/json",
})
req.body = { token: token }.to_json
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) { |h| h.request(req) }
user = JSON.parse(res.body)

Webhooks

typescript
type WordKeyWebhookEvent =
  | { type: "auth.success", user: WordKeyUser, isNewUser: boolean }
  | { type: "auth.failed", reason: string }
  | { type: "user.word_changed", userId: string }
  | { type: "user.disconnected", userId: string };

// Verify the signature (HMAC-SHA256 with your API key):
const ok = await wk.verifyWebhook(rawBody, req.headers["x-wordkey-signature"]);

API reference

POST/api/auth/token-verify

Verify a client token. Bearer API key. Returns userId, isNewUser.

POST/api/sdk/user-exists

Check if a user id exists.

POST/api/sdk/user-events

Recent auth events for a user at your business.

POST/api/auth/roaming/create

Open a roaming session; returns a QR payload.

GET/api/auth/roaming/status/:key

Poll roaming status; returns token when approved.