developers

Get an API key.

Self-service. Free for testing. The public key goes in your client SDK, the secret stays on your server. Both rotate any time from the portal.

Test keys are issued instantly, capped at 1,000 req/h (tenant-wide), and rotate anytime. Live keys lift the cap to 10,000 req/h. Billing is pay-per-call: 1,000 free calls/month, no card needed. Add a card or buy a prepaid credit pack to remove the cap.

Pick client when you embed a pk_test_ in browser code. With GRAYPASS_REQUIRE_KEY_SCOPE=1, client keys are rejected from mutating routes (key create, webhook CRUD, GDPR erase, etc.) so a leaked browser key can't escalate.

By generating a key you agree to our terms.

Save these now.

We don't store the secret key in plaintext. If you lose it you'll have to rotate.

public_key

secret_key

The secret key gives full tenant access. Never embed it in client code, never commit it.
Quickstart guide

5 min quickstart

Drop-in install.

Add the SDK in your client, the middleware on your server. That's it.

npm install @graypass/sdk

import { GrayPassV2 } from "@graypass/sdk";

// init returns a client instance - keep it around for the session lifetime
const gp = GrayPassV2.init({ apiKey: "pk_test_…" });

// startSession returns V2SessionStartResponse - snake_case fields, mirrors the JSON API.
const { session_id, enrolled, trust, state } = await gp.startSession({ userId: "user_42" });

gp.on("trust_change", ({ confidence, state, reasons }) => {
  console.log("trust ->", confidence, state, reasons);
});

// when the user clicks "Open dashboard":
const verdict = await gp.authorize("dashboard.example.com", { minTrust: 0.7 });
if (verdict.authorized) {
  document.cookie = `gp_token=${verdict.token}; Secure; SameSite=Lax`;
} else {
  // verdict.fallback ∈ {step_up_required, re_authenticate, wait_for_trust, session_killed}
}