Docs

JavaScript: install and configure

Install @sovaria/sdk, where it runs, create a client for browsers and for servers, every configuration option, sessions, retries and idempotency, errors and their codes, and fixes for common setup problems.

Updated Oct 17, 2026

Install

npm install @sovaria/sdk
Runs inNotes
BrowsersModern evergreen browsers. Sessions persist in localStorage by default.
Node.jsAny version with global fetch (18+). Pass fetchImpl to use another implementation.
Deno, Bun, edge runtimesUses the global fetch and Web Crypto.
React NativepersistSession: { storage } takes a synchronous store (getItem, setItem, removeItem — for example MMKV). With an async store such as AsyncStorage, save tokens from onTokenRefreshSensitive and restore them with setAccessToken / setRefreshToken (Sign-in for mobile apps).

Create a client

import { createClient } from '@sovaria/sdk'

export const sovaria = createClient(
  import.meta.env.VITE_SOVARIA_URL,        // https://<project-ref>.sovarias.in
  import.meta.env.VITE_SOVARIA_ANON_KEY,
)

One client per app (or per request on a server acting for users). The URL names the project, so no ids are needed. Which key goes where: Connect your app; variable names: Environment variables.

Options

OptionDefaultWhat it does
persistSessionOn in browsers when an anon key is giventrue keeps the session in localStorage; false keeps it in memory only; { storage, key } uses another synchronous store.
onTokenRefresh—Called with new tokens after sign-in or refresh (without the refresh token).
onTokenRefreshSensitive—The same, including the refresh token — store it securely, never log it.
accessToken, expiresIn—Start with an existing token.
envIdProductionTalk to another environment of the project.
orgId, projectIdDiscovered from the URLPin them for multi-project tools.

Retry and transport settings are set when you construct the client directly: new SovariaSDK({ baseUrl, accessToken, refreshToken, persistSession, fetchImpl, retryCount, retryBaseDelayMs }).

Retries and idempotency

  • Requests that fail with 429, 500, 502, 503 or 504, or with a network error, are retried — 4 attempts in all by default (retryCount), with jittered exponential backoff from 100 ms (retryBaseDelayMs, at most 10 s). After a 429 the SDK waits at least the Retry-After time.
  • Writes (POST, PUT, PATCH, DELETE) are retried too, and a retried write is applied once: every write carries one Idempotency-Key from its first attempt, so if the server applied it but the response was lost, the retry gets the stored answer instead of running it again. A retry that arrives while the first try is still running waits for it.
  • The key belongs to one call. To make a write safe for your own code to repeat (after a crash or a page reload, say), pass a key you can recreate, such as order-<id>: sovaria.request(method, path, { body, idempotencyKey }). The server keeps the answer for an hour (two minutes when it carries tokens or keys); the same key with a different body gets 409 IDEMPOTENCY_PAYLOAD_MISMATCH. idempotent: true is no longer needed and is still accepted.
  • Access tokens are refreshed a minute before they expire, and once more after a 401; you don't need to handle expiry yourself.

Errors

Failed calls throw SovariaError with a stable code to branch on and a message you can show to users:

import { SovariaError } from '@sovaria/sdk'

try {
  await sovaria.data.sql('insert into orders (total) values ($1)', [42])
} catch (err) {
  if (!(err instanceof SovariaError)) throw err
  switch (err.code) {
    case 'UNAUTHENTICATED': return goToSignIn()
    case 'PERMISSION_DENIED': return toast('You can\'t do that.')
    case 'PLAN_LIMIT_REACHED':
    case 'PLAN_QUOTA_EXHAUSTED': return showUpgrade(err.detail)
    case 'RATE_LIMITED': return toast('Too many requests — try again in a moment.')
    default: console.error(err.technicalMessage); toast(err.message)
  }
}
FieldValue
codeNETWORK_ERROR, UNAUTHENTICATED, PERMISSION_DENIED, NOT_FOUND, CONFLICT, INVALID_INPUT, PAYLOAD_TOO_LARGE, UNSUPPORTED_TYPE, RATE_LIMITED, PLAN_LIMIT_REACHED, PLAN_FEATURE_REQUIRED, PLAN_QUOTA_EXHAUSTED, SERVICE_UNAVAILABLE, SERVER_ERROR, BAD_REQUEST, CONFIG_ERROR, UNKNOWN
messageA friendly sentence for end users.
statusCodeThe HTTP status (0 when no response arrived).
serverCodeThe server's own code when it sent one (SIGNUP_DISABLED, …).
detailThe response body.
technicalMessageHTTP <status>: <server text> for logs.

Troubleshooting

SymptomFix
403 ORIGIN_NOT_ALLOWED in the browserAdd your site's origin under Project Settings › API (Allowed origins (CORS) for browser apps).
CONFIG_ERROR at start-up (Missing portal URL, Missing SOVARIA_URL)The URL isn't set — check the variable names and that your bundler exposes them (VITE_, NEXT_PUBLIC_).
Warning: publishableKey looks like a user JWTA session token was passed where the anon key belongs; pass tokens with setAccessToken.
Signed out after every reloadSessions persist by default only in browsers with an anon key; on servers pass the user's token per request.
Every call is PERMISSION_DENIEDYour rules don't allow it yet — see How access is decided.
Something unclear or missing on this page?Tell us