Bring your own MongoDB. Get a production-ready backend in 60 seconds.
your backend β your database β your rules.
Dashboard Β· Docs Β· Quick Start Β· Discord
License: Core apps/packages are AGPL-3.0-only Β· examples and @urbackend/sdk are MIT.
Contributions currently do not require CLA/DCO; submitted changes are licensed under the package license they modify (details in CONTRIBUTING.md).
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 SDK:
- Node.js / TS:
npm install @urbackend/sdk - Python:
pip install urbackend
- Node.js / TS:
- 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
});from urbackend import UrBackendClient
# Initialize with your API key
client = UrBackendClient(api_key='YOUR_API_KEY')
# Read data (GET /api/data/products)
products = client.db.get_all('products')
# Write data (POST /api/data/products)
# requires sk_live_* key or RLS enabled
product = 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 |
By default, new users can sign up using email/password or social providers. You can disable public signups from the Authentication page in the dashboard under the Allow Public Signups toggle. When disabled, the API blocks new registrations, allowing only existing users to log in.
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. . .
