Choose your auth mode
Two ways to authenticate the SDK — a decision tree for whether you need a static API key or a per-user session JWT.
The SDK supports two auth modes. Picking the right one depends on where the code that calls the SDK actually runs — not which is more convenient.
The decision tree
Is this code running on your server (Node.js backend, cron job, internal service)?
→ API key mode is available. Pass your key as apiKey. Generate one self-service from your
app’s detail page in the Console (Regenerate API Key) — see Get your API
key — or use session JWT mode below
if you’d rather not manage a static key.
const ai = new Quravin({
endpoint: process.env.QURAVIN_URL,
apiKey: process.env.QURAVIN_KEY, // from your secrets store — never commit
});
Is this code running in a user’s browser?
→ Use session JWT mode. Your server mints a short-lived, per-user token and hands it to the
page — the browser never sees client_secret or a static API key.
const ai = new Quravin.Quravin({
endpoint: "https://api.quravin.com",
sessionToken: await fetchToken(), // from your own backend endpoint
onTokenExpired: fetchToken, // auto-refresh on 401
});
x-api-key vs. session JWT — they are not interchangeable
apiKey above sends the request as x-api-key: <key>. This is a legacy, app-level,
non-org-scoped credential that the platform is phasing out in favor of per-user JWTs. Two
things to know before you reach for it:
- No org wallet. If your account is on wallet-mode billing, a billable
POST /ticketscall authenticated with a barex-api-keyreturns 402insufficient_creditseven when your org’s wallet has funds — the key isn’t attached to an org, so it can’t spend from one. This is by design, not a bug. - No per-user identity. Every call looks like it came from “the app,” not a specific user —
fine for a cron job, not fine if you need per-user audit/attribution or a
pipelines[]ACL scoped tighter than the whole app.
If billing or per-user attribution matters at all, use session JWT mode — mint it via
POST /auth/token, not x-api-key. If multiple tenants or customers share the same backend
process or credential, use session JWT mode too — it scopes each caller to its own tickets, unlike
a bare x-api-key.
Minting a session JWT: POST /auth/token
Your backend mints a short-lived JWT per user by calling the platform’s POST /auth/token
endpoint, authenticated with the client_id/client_secret pair from Get your API
key as HTTP Basic auth:
curl -X POST "https://api.quravin.com/auth/token" \
-H "Authorization: Basic $(echo -n 'client_id:client_secret' | base64)" \
-H "Content-Type: application/json" \
-d '{
"subject": "user-12345",
"pipelines": ["translate-string"],
"ttl_seconds": 900
}'
Response:
{ "token": "eyJhbGciOi...", "token_type": "Bearer", "expires_in": 900 }
subject(required) — your app’s id for this user; becomes the JWTsub.pipelines(optional) — the ACL you want on this token. A user can only call pipelines listed in your Application’sallowed_pipelines(set in the Console, see Get your API key) — whatever you request here is intersected with that allow-list server-side, so you can’t grant a user more than your app itself is allowed. Omit this field to get the token scoped to your app’s full allow-list.ttl_seconds(optional) — token lifetime, clamped to 60–3600 seconds, default 900 (15 min).
Hand the returned token to the browser as sessionToken. See Integrate into your own
server for the full endpoint + browser wiring, and
for the legacy self-signing alternative that uses a separately-provisioned signing secret instead
of client_id/client_secret.
Why this matters
A static API key is a bearer credential — anyone who reads it from your page source has full
access to everything your app can do. A session JWT is scoped to one user, expires in minutes,
carries a pipelines[] ACL, and is minted fresh by your own server on every page load.
Rule of thumb: if the code ships to a browser, or if billing/per-user attribution matters, it needs a session JWT, not a static API key.
Next: Integrate into your own server shows the token-minting endpoint that issues session JWTs.