Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.ub.bitbros.in/llms.txt

Use this file to discover all available pages before exploring further.

The two keys

Every project gets exactly two API keys when it is created.
KeyPrefixWhere to useDefault write access
Publishable keypk_live_...Frontend, browser, mobile appRead-only — writes blocked unless RLS is enabled
Secret keysk_live_...Server-side only (Node.js, serverless functions, etc.)Full read and write access
Both keys are found in Settings in your project dashboard.

How to pass the key

Include the key in the x-api-key request header on every API call:
x-api-key: pk_live_...
No other authentication format is accepted for project-level authorization. The header name is lowercase and hyphenated exactly as shown.

Using the publishable key

Use pk_live for all read operations from client-side code. It is safe to bundle in browser JavaScript, React Native apps, or any publicly visible context.
// Safe — pk_live is read-only by default
const response = await fetch('https://api.ub.bitbros.in/api/data/products', {
  headers: {
    'x-api-key': 'pk_live_...'
  }
});

const { data } = await response.json();
By default, pk_live is blocked from all write operations (POST, PUT, PATCH, DELETE). Attempting a write with only pk_live returns:
{ "success": false, "message": "Write blocked for publishable key" }

Enabling writes with pk_live

You can allow authenticated frontend users to write their own data by enabling Row-Level Security (RLS) on a collection. When RLS is on, pk_live writes are accepted — but only when the request also includes a valid user JWT in the Authorization header, and only for documents the user owns.
// pk_live write with RLS enabled — user must be logged in
const response = await fetch('https://api.ub.bitbros.in/api/data/posts', {
  method: 'POST',
  headers: {
    'x-api-key': 'pk_live_...',
    'Authorization': `Bearer ${userToken}`,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({ title: 'My post', content: '...' })
});
See Row-Level Security for the full setup and behavior details.

Using the secret key

Use sk_live for all server-side operations: seeding data, admin scripts, serverless API routes, and any write that happens outside a user’s own browser session.
// Server-side only — never expose sk_live in client code
const response = await fetch('https://api.ub.bitbros.in/api/data/products', {
  method: 'POST',
  headers: {
    'x-api-key': 'sk_live_...',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({ name: 'Widget', price: 9.99 })
});
sk_live bypasses RLS entirely and always has full read and write access on all collections (except /api/data/users*, which is always blocked — use /api/userAuth/* instead).
Never include your sk_live key in frontend code, client-side JavaScript bundles, mobile apps, or any public repository. Treat it like a database password. If it is exposed, rotate it immediately from your project settings.

Environment variable pattern

Store your keys in environment variables and never commit them to source control:
# .env (add to .gitignore)
VITE_URBACKEND_KEY=pk_live_xxxxxx   # safe to expose to the browser via VITE_
URBACKEND_SECRET=sk_live_yyyyyy      # server-side only, never prefix with VITE_
// In your frontend code
const apiKey = import.meta.env.VITE_URBACKEND_KEY; // pk_live

// In your server/API route
const secretKey = process.env.URBACKEND_SECRET; // sk_live

Key behavior summary

ScenarioKeyTokenResult
Read any collectionpk_liveNot requiredAllowed
Write, RLS disabledpk_liveAny403 blocked
Write, RLS enabled, no tokenpk_liveMissing401 unauthorized
Write, RLS enabled, correct ownerpk_liveMatching userIdAllowed
Write, RLS enabled, wrong ownerpk_liveDifferent userId403 owner mismatch
Any writesk_liveNot requiredAllowed
Access /api/data/users*AnyAny403 blocked — use /api/userAuth/*
A good rule of thumb: use pk_live for everything your users’ browsers do, and sk_live for everything your server does.