Build your backend
without the busywork.
Use PostgreSQL tables, a REST API, application authentication, distributed file storage, realtime events, and Edge Functions from one Nodvian project.
https://nodvian.cloudAPI versionv1FormatJSONQuickstart
- Create an account and project.Open the Nodvian dashboard, choose Developer, then name your workspace and project.
- Create a table.Open Database → Tables. Create a table named
taskswithtitleandstatuscolumns. - Create an API key.Open Settings → API keys. Choose the smallest permission your app needs and restrict the key to your production domain.
- Call the API.Store the key in an environment variable, never directly in browser source.
const NODVIAN_URL = "https://nodvian.cloud";
const NODVIAN_KEY = process.env.NODVIAN_API_KEY;
const response = await fetch(`https://nodvian.cloud/api/v1/tasks`, {
headers: { Authorization: `Bearer ${NODVIAN_KEY}` }
});
const { data } = await response.json();
console.log(data);Project setup
A Nodvian account contains one workspace and project in the current release. Your project owns its tables, application users, API keys, stored objects, functions, realtime events, and logs.
Add a pooled PostgreSQL connection as DATABASE_URL. Nodvian creates an isolated schema for your project.
Use the dashboard for tables, SQL, app users, email delivery, storage metadata, functions, and logs.
Every public project request uses the versioned /api/v1 endpoints below.
API keys
Create keys in Settings → API keys. The complete key is shown once. Store it in a server-side secret such as NODVIAN_API_KEY.
read_onlyGET requests onlyread_writeRead, create, update, and deletefull_accessAll currently supported project API operationsDomain restrictions Set a hostname such as app.example.com to accept browser requests only from that hostname and its subdomains. Use * only for server-to-server development. Send the key as Authorization: Bearer YOUR_KEY.
Database
Tables use PostgreSQL. A table name or column must begin with a letter or underscore and may contain letters, numbers, and underscores. New tables automatically receive id, created_at, and updated_at fields.
Create and inspect tables visually, add rows, or run validated SQL from the dashboard SQL editor. API responses return { "data": ... }.
REST API
/api/v1/:tableReturn up to 500 rows, newest updates first.
/api/v1/:tableCreate a row. Unknown fields are ignored and Nodvian creates the row ID.
/api/v1/:table?id=ROW_IDUpdate supplied fields on one row.
/api/v1/:table?id=ROW_IDDelete one row and return its ID.
curl -X POST https://nodvian.cloud/api/v1/tasks \
-H "Authorization: Bearer $NODVIAN_API_KEY" \
-H "Content-Type: application/json" \
-d '{"title":"Ship the app","status":"open"}'curl -X PATCH "https://nodvian.cloud/api/v1/tasks?id=ROW_ID" \
-H "Authorization: Bearer $NODVIAN_API_KEY" \
-H "Content-Type: application/json" \
-d '{"status":"done"}'Application authentication
Nodvian can manage the users of your application separately from your Nodvian dashboard account. Signup and login use the project API key. Successful authentication returns an ndv_user_… access token valid for 30 days.
/api/v1/auth/signupCreate an application user and session.
/api/v1/auth/loginSign in with email and password.
/api/v1/auth/userRead the current user with their user access token.
/api/v1/auth/logoutRevoke the presented user access token.
/api/v1/auth/password-reset/requestSend a one-time reset link to an allowed HTTPS redirect URL.
/api/v1/auth/password-reset/confirmSet a new password using the one-time token.
const response = await fetch("https://nodvian.cloud/api/v1/auth/signup", {
method: "POST",
headers: {
Authorization: `Bearer ${NODVIAN_API_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
email: "user@example.com",
password: "StrongPass1!"
})
});
const { user, session } = await response.json();
localStorage.setItem("nodvian_session", session.accessToken);const token = localStorage.getItem("nodvian_session");
const response = await fetch("https://nodvian.cloud/api/v1/auth/user", {
headers: { Authorization: `Bearer ${token}` }
});
const { user } = await response.json();Passwords require at least 10 characters, uppercase and lowercase letters, a number, and a symbol. Reset links expire after 15 minutes and revoke the user’s existing sessions after use.
Distributed storage
Objects are stored through healthy Nodvian host nodes. Nodvian does not silently fall back to another cloud when no node is online.
/api/v1/storage/:idUpload binary content using an ID containing letters, numbers, dots, underscores, or hyphens.
/api/v1/storage/:idDownload content. Range requests are supported.
/api/v1/storage/:idDelete the stored shard.
/api/v1/storage/:id/signCreate a shareable signed download URL.
const objectId = crypto.randomUUID();
const bytes = await file.arrayBuffer();
const response = await fetch(`https://nodvian.cloud/api/v1/storage/${objectId}`, {
method: "PUT",
headers: {
Authorization: `Bearer ${NODVIAN_API_KEY}`,
"Content-Type": "application/octet-stream"
},
body: bytes
});const response = await fetch(
`https://nodvian.cloud/api/v1/storage/${objectId}/sign`,
{
method: "POST",
headers: {
Authorization: `Bearer ${NODVIAN_API_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({ expiresIn: 900 })
}
);
const { url, expiresAt } = await response.json();Signed links default to 15 minutes and can be set from 60 seconds to 24 hours. Downloads report X-Nodvian-Node and X-Nodvian-Cache headers.
Realtime events
Each REST insert, update, or delete creates a project event containing the table, operation, row ID, payload, and timestamp. Use the stream for live clients or polling when your environment cannot attach authorization to an event stream.
/api/v1/realtimeOpen the realtime event stream.
/api/v1/realtime?stream=0&after=EVENT_IDReturn the next event batch after a known event ID.
// Open a text/event-stream response with fetch so the
// Authorization header can be included.
const response = await fetch("https://nodvian.cloud/api/v1/realtime", {
headers: { Authorization: `Bearer ${NODVIAN_KEY}` }
});
const reader = response.body.getReader();
const decoder = new TextDecoder();
while (true) {
const { value, done } = await reader.read();
if (done) break;
console.log(decoder.decode(value, { stream: true }));
}Edge Functions
Create functions in the dashboard with a lowercase URL slug, response status, content type, and response body. Responses may use {{method}}, {{timestamp}}, and {{path}} placeholders.
/api/v1/functions/:slugInvoke an enabled function with a project API key.
curl https://nodvian.cloud/api/v1/functions/hello-world \
-H "Authorization: Bearer $NODVIAN_API_KEY"Host a Nodvian node
Hosts provide storage capacity to the network. Get approved, create a private enrollment key, install the package for your system, and keep the service online. Enrollment keys start with ndv_node_ and must remain private.
# Ubuntu x86_64
curl -fLO https://nodvian.cloud/NodvianNode-Linux-amd64.tar.gz
tar -xzf NodvianNode-Linux-amd64.tar.gz
cd nodvian-node-linux-amd64
sudo ./install.sh
sudo nano /etc/nodvian-node.env
sudo systemctl enable --now nodvian-node
sudo systemctl status nodvian-node --no-pagerThe environment file at /etc/nodvian-node.env contains NODVIAN_NODE_KEY, region, storage size, storage path, and config directory. After editing in nano, press Ctrl+O, Enter, then Ctrl+X.
At least 100 GB available.
25 Mbps download, 10 Mbps upload.
250 ms or less to the relay.
Current limits
Errors and troubleshooting
400Invalid JSON, field, query, or identifier401Missing, invalid, expired, or revoked token403Key permission or domain restriction rejected the request404Table, row, function, or object was not found409Duplicate resource or project limit reached429Authentication or bandwidth limit reached503Required database, relay, node, or function is unavailableEvery JSON error includes a human-readable message. Check Project Logs for API, database, authentication, function, storage, and security activity.
Production security checklist
- Keep project and enrollment keys in server-side secrets.
- Create separate keys for development and production.
- Use
read_onlywhenever writes are unnecessary. - Restrict browser-facing keys to your exact application domain.
- Revoke a key immediately if it appears in source control or logs.
- Use signed URLs instead of exposing API keys for file downloads.
- Treat user access tokens like passwords and clear them on logout.
- Review Project Logs and authentication rate limits before launch.
