Bring your own MongoDB. Get a production-ready backend in 60 seconds.
your backend β your database β your rules.
Dashboard Β· Docs Β· Quick Start Β· Discord
urBackend is an Open-Source BaaS built to eliminate the complexity of backend management. It provides everything you need to power your next big ideaβaccessible via a unified REST API.
| Feature | Description |
|---|---|
| Instant NoSQL | Create collections and push JSON data instantly with zero boilerplate. |
| Managed Auth | Sign Up, Login, and Profile management with JWT built-in. |
| Cloud Storage | Managed file/image uploads with public CDN links. |
| BYO Database | Connect your own MongoDB Atlas or self-hosted instance. |
| Real-time Analytics | Monitor traffic and resource usage from a premium dashboard. |
| Unique Constraints | Enforce field uniqueness (e.g., username, email) at the database level. |
| Secure Architecture | Dual-key separation (pk_live & sk_live) for total safety. |
Go from zero to a live backend in under 60 seconds.
- Initialize: Create a project on the Dashboard.
- Install:
npm install @urbackend/sdk - Model: Visually define your collections and schemas.
- Execute: Push and pull data immediately using the SDK.
import urBackend from '@urbackend/sdk';
// Initialize with your API key
const client = urBackend({ apiKey: 'YOUR_API_KEY' });
// Read data (GET /api/data/products)
const products = await client.db.getAll('products');
// Write data (POST /api/data/products)
// requires sk_live_* key or RLS enabled
const product = await client.db.insert('products', {
name: 'Widget',
price: 9.99
});Understanding which key to useβand whenβprevents the most common integration mistakes.
| Scenario | Key | Auth Token | Result |
|---|---|---|---|
| Read any collection | pk_live |
Not required | β Allowed |
| Write to a collection (RLS disabled) | pk_live |
Any | β 403 Blocked |
| Write to a collection (RLS disabled) | sk_live |
Not required | β Allowed |
| Write to a collection (RLS enabled, no token) | pk_live |
Missing | β 401 Unauthorized |
| Write to a collection (RLS enabled, wrong owner) | pk_live |
Token with different userId | β 403 Owner mismatch |
| Write to a collection (RLS enabled, correct owner) | pk_live |
Token with matching userId | β Allowed |
| Write to a collection (RLS enabled, no ownerField) | pk_live |
Valid token | β Allowed (userId auto-injected) |
Access /api/data/users* |
Any | Any | β 403 Blocked β use /api/userAuth/* |
Rule of thumb:
pk_liveis for frontend reads. Usesk_livefor server-side writes, or enable collection RLS to allow authenticated users to write their own data withpk_live.
RLS lets you safely allow frontend clients to write data without exposing your secret key. When enabled on a collection, pk_live writes are gated by user ownership and reads can be scoped by mode.
How it works:
- Enable RLS for a collection in the Dashboard and choose a mode.
- Use
public-readfor content anyone can view, orprivatefor owner-only access. (owner-write-onlyis treated aspublic-readfor legacy projects.) - Choose the owner field β the document field that stores the authenticated user's ID (e.g.,
userId). - The client must send a valid user JWT in the
Authorization: Bearer <token>header forpk_livewrites and forprivatereads. - urBackend enforces that the JWT's
userIdmatches the document's owner field.
Example β user creates a post:
// 1. User logs in (POST /api/userAuth/login)
const { accessToken } = await client.auth.login({
email: 'user@example.com',
password: 'secret'
});
// 2. User creates a post (POST /api/data/posts)
// accessToken is auto-handled by the SDK after login
const post = await client.db.insert('posts', {
title: 'Hello World',
content: '...'
});
// The saved document will include: { userId: '<logged-in user id>', title: 'Hello World', ... }Common failure cases:
| Error | Cause | Fix |
|---|---|---|
403 Write blocked for publishable key |
RLS is not enabled on the collection | Enable RLS in Dashboard, or use sk_live |
401 Authentication required |
No Authorization header provided |
Add Authorization: Bearer <user_jwt> |
403 RLS owner mismatch |
Token's userId β document's owner field |
Make sure the user is writing their own data |
403 Insert denied (ownerField _id) |
_id is not a valid owner field for inserts |
Change ownerField to userId or similar |
403 Owner field immutable |
Trying to change the owner field on update | Remove the owner field from the PATCH/PUT body |
Social Auth is configured in a Supabase-style flow:
- Set your project's
Site URLin Project Settings. - Open
Auth -> Social Authin the dashboard. - Copy the read-only callback URL shown for GitHub or Google.
- Register that callback URL in the provider console.
- Paste the provider
Client IDandClient Secretinto urBackend and enable the provider.
After a successful provider login, urBackend redirects users back to:
<Site URL>/auth/callback
The frontend callback flow is:
- Read
tokenfrom the URL fragment andrtCodefrom the query string. - Call
POST /api/userAuth/social/exchangewith JSON:tokenrtCode
- Expect a standard response in the form
{ success, data, message }. - On success, store the original access token together with
data.refreshToken. - Continue into the signed-in app.
Callback example:
// After redirect from provider (POST /api/userAuth/social/exchange)
const token = new URLSearchParams(window.location.hash.slice(1)).get('token');
const rtCode = new URLSearchParams(window.location.search).get('rtCode');
const { refreshToken } = await client.auth.socialExchange({ token, rtCode });
// Success shape: { refreshToken }GitHub and Google both support:
- linking existing users by email when the provider returns a verified email matching an existing account
- creating new users automatically when no matching account exists
- issuing the same urBackend access and refresh tokens used by normal auth flows
- backend-generated read-only provider callback URLs in the dashboard
- redirecting to the project
Site URLafter provider login
User accounts are managed through the SDK's auth module β not through the database API. Direct access to /api/data/users* is blocked for security.
// Sign up a new user (POST /api/userAuth/signup)
await client.auth.signUp({
email: "user@example.com",
password: "secret",
name: "Alice"
});
// Log in (POST /api/userAuth/login)
const { accessToken, user } = await client.auth.login({
email: "user@example.com",
password: "secret"
});
// Get current user profile (GET /api/userAuth/me)
// Uses the accessToken from the previous login automatically
const me = await client.auth.me();All auth methods require your pk_live key. See the full auth docs for more.
graph LR
A[1. Connect MongoDB] --> B[2. Define Collections]
B --> C[3. π Instant REST APIs]
C --> D[4. Scale & Monitor]
Explore our Architecture Diagram to understand the system design, core components, and data flow in detail.
Want to run your own instance? Follow the step-by-step guide to deploy urBackend to Render (backend) and Vercel (frontend) using free-tier services β no Docker required.
π DEPLOYMENT.md
Join hundreds of developers building faster without the backend headaches.
- GitHub Issues: Report bugs & request features.
- Discord Channel: Join the conversation.
- Contributing: Help us grow the ecosystem.
Built with β€οΈ by the urBackend community. . .
