Bani Studio Documentation
Everything you need to set up, configure, and integrate Bani Studio — your AI-powered app builder.
How it works
Users describe what they want to build in plain text (Arabic or English). The AI generates a full-stack web app — HTML, CSS, JavaScript, and optionally a Node.js backend — deploys it on a subdomain, and gives the user a live URL within minutes.
Each build costs 2 credits. Running a live app costs 1 credit per day. Credits can be purchased as one-time packs or included in monthly subscriptions.
Credits & Billing
| Action | Cost |
|---|---|
| AI build | 2 credits |
| Live app per day | 1 credit |
| PostgreSQL provision | 10 credits |
Credit packs (one-time)
| Pack | Credits | Builds | Price |
|---|---|---|---|
| Starter | 60 | 30 | $5 |
| Builder | 250 | 125 | $20 |
| Pro | 700 | 350 | $50 |
Monthly subscriptions
| Plan | Credits/month | Builds/month | Price |
|---|---|---|---|
| Starter | 100 | 50 | $15/mo |
| Builder | 300 | 150 | $39/mo |
| Studio | 700 | 350 | $99/mo |
Your Apps
Every app gets a free subdomain: yourapp.elbani.studio. Custom domains require connecting via workspace settings.
You own everything. Download a ZIP export any time — it includes all source code, a Dockerfile, and a README. Deploy it anywhere: Docker, Vercel, Railway, your own server.
SendGrid (email)
Bani Studio sends transactional emails: account verification, password reset, welcome, build-done notifications, low-credit warnings.
Create a SendGrid account
Go to sendgrid.com → free plan includes 100 emails/day.
Verify your sender domain
Settings → Sender Authentication → Authenticate a domain → enter elbani.studio → add the DNS records they give you.
Create an API key
Settings → API Keys → Create API Key → give it "Mail Send" permission → copy the key (starts with SG.).
Set environment variables
SENDGRID_API_KEY=SG.xxxxxxxxxxxxxxxxxxxxxxxx
SMTP_FROM=noreply@elbani.studio
EMAIL_FROM_NAME=Bani Studio
Or use generic SMTP credentials from SendGrid (Settings → API Keys → SMTP relay):
SMTP_HOST=smtp.sendgrid.net
SMTP_PORT=587
SMTP_USER=apikey
SMTP_PASS=SG.xxxxxxxxxxxxxxxxxxxxxxxx
SMTP_FROM=noreply@elbani.studio
Stripe (billing)
Handles credit pack purchases and monthly subscription payments.
Get your Stripe keys
Dashboard → Developers → API keys → copy Secret key and Publishable key.
Create products in Stripe
Create one product per credit pack and one per subscription plan. The Price IDs are stored in server.js — update CREDIT_PACKS and SUBSCRIPTION_PLANS with your real Stripe Price IDs.
Set up webhook
Stripe Dashboard → Webhooks → Add endpoint → URL: https://elbani.studio/api/credits/webhook → Events: checkout.session.completed, customer.subscription.created, customer.subscription.updated, customer.subscription.deleted.
Set environment variables
STRIPE_SECRET_KEY=sk_live_xxxxxxxxxxxxxxxx
STRIPE_WEBHOOK_SECRET=whsec_xxxxxxxxxxxxxxxx
MongoDB (database)
By default, Bani Studio stores all data in JSON files on disk (/app/data/). When MONGODB_URL is set, it automatically switches to MongoDB and migrates existing data.
Create a MongoDB Atlas cluster
Go to cloud.mongodb.com → Create a free cluster → choose Azure or the nearest region.
Create a database user
Security → Database Access → Add new user → username bani → auto-generate password → copy it.
Whitelist IP / allow all
Security → Network Access → Add IP Address → 0.0.0.0/0 (allow from anywhere, needed for Azure Container App).
Get connection string
Connect → Drivers → copy the connection string. Replace <password> with your actual password.
MONGODB_URL=mongodb+srv://bani:yourpassword@cluster0.xxxxx.mongodb.net/bani
MONGODB_DB=bani
GitHub (auto-push)
Users can connect a GitHub repo to any app. After each successful build, code is automatically pushed to the linked repo.
Create a GitHub OAuth App
GitHub → Settings → Developer settings → OAuth Apps → New OAuth App
- Homepage URL:
https://elbani.studio - Authorization callback URL:
https://elbani.studio/api/auth/github/callback
Set environment variables
GITHUB_CLIENT_ID=Ov23lixxxxxxxxxxxxxxxx
GITHUB_CLIENT_SECRET=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Azure Blob Storage (backup)
When configured, Bani Studio automatically backs up all data files to Azure Blob Storage daily at 3am UTC.
Create a Storage Account
Azure Portal → Storage accounts → Create → choose the same region as your Container App.
Get connection string
Your storage account → Security + networking → Access keys → copy Connection string.
Set environment variables
AZURE_STORAGE_CONNECTION_STRING=DefaultEndpointsProtocol=https;AccountName=...
AZURE_BACKUP_CONTAINER=bani-backups
All Environment Variables
Set these in your Azure Container App → Settings → Environment variables (or in a .env file for local development).
Core
| Variable | Description | Default | |
|---|---|---|---|
| JWT_SECRET | Secret key for signing auth tokens. Change this in production. | bani-secret-change-me | REQUIRED |
| PORT | HTTP port the server listens on | 3000 | optional |
| DOMAIN | Root domain for subdomains | elbani.studio | optional |
| BASE_URL | Full URL of the platform (used in emails) | https://elbani.studio | optional |
| OWNER_EMAIL | Admin account email — auto-created on startup | malhajeri@cultureyes.ae | optional |
| NODE_ENV | Set to production to hide internal error details |
— | recommended |
| ANTHROPIC_API_KEY | Claude AI key for building apps | — | REQUIRED |
| PROJECTS_DIR | Where deployed app files are stored | /app/projects | optional |
| DATA_DIR | Where JSON data files are stored | /app/data | optional |
Email (SendGrid / SMTP)
| Variable | Description | Default | |
|---|---|---|---|
| SENDGRID_API_KEY | SendGrid API key (starts with SG.) — alternative to SMTP_* vars | — | recommended |
| SMTP_HOST | SMTP server hostname (e.g. smtp.sendgrid.net) | — | recommended |
| SMTP_PORT | SMTP port | 587 | optional |
| SMTP_USER | SMTP username (for SendGrid: apikey) | — | optional |
| SMTP_PASS | SMTP password (for SendGrid: your API key) | — | optional |
| SMTP_FROM | From address for outgoing emails | noreply@elbani.studio | optional |
| EMAIL_FROM_NAME | Sender name in emails | Bani Studio | optional |
Stripe
| Variable | Description | Default | |
|---|---|---|---|
| STRIPE_SECRET_KEY | Stripe secret key (sk_live_... or sk_test_...) | — | recommended |
| STRIPE_WEBHOOK_SECRET | Stripe webhook signing secret (whsec_...) | — | recommended |
MongoDB
| Variable | Description | Default | |
|---|---|---|---|
| MONGODB_URL | MongoDB connection string (mongodb+srv://...) | — (uses JSON files) | recommended |
| MONGODB_DB | MongoDB database name | bani | optional |
GitHub
| Variable | Description | Default | |
|---|---|---|---|
| GITHUB_CLIENT_ID | GitHub OAuth App client ID | — | optional |
| GITHUB_CLIENT_SECRET | GitHub OAuth App client secret | — | optional |
Azure Backup
| Variable | Description | Default | |
|---|---|---|---|
| AZURE_STORAGE_CONNECTION_STRING | Azure Blob Storage connection string for backups | — | optional |
| AZURE_BACKUP_CONTAINER | Container name for backup files | bani-backups | optional |
PostgreSQL (per-app databases)
| Variable | Description | Default | |
|---|---|---|---|
| PG_HOST | PostgreSQL host for provisioning user databases | — | optional |
| PG_PORT | PostgreSQL port | 5432 | optional |
| PG_USER | PostgreSQL admin username | — | optional |
| PG_PASSWORD | PostgreSQL admin password | — | optional |
| PG_ADMIN_DB | PostgreSQL admin database name | postgres | optional |
App Secrets
Each user app can store secrets (environment variables) that are injected into the running process but never exposed to the AI or in exports.
Add secrets in the workspace → Settings tab → Environment Variables section. They're stored encrypted in the app record and passed as process.env.VARIABLE_NAME to your app at runtime.
Custom Domains
Every app gets appname.elbani.studio automatically (wildcard SSL certificate covers all subdomains).
To add a custom domain: workspace → Settings → Custom Domain → enter your domain → add a CNAME record pointing to elbani.studio with your DNS provider.
API — Authentication
All protected endpoints require a Bearer token in the Authorization header:
Authorization: Bearer <your-jwt-token>
Get a token by calling POST /api/auth/login.
{ email, password, name? }{ email, password }. Returns { token, user }.{ email }. Rate limited.API — Apps
{ name, framework?, prompt? }.API — Credits
{ packId }.{ planId }.API — Admin
All admin endpoints require an admin account.
{ amount, reason }.