DBmuse for developers
Manage your DBmuse workspace from your own code: a REST API with scoped keys and per-key rate limits over your projects and the database connections registered in them, plus signed webhooks when any of it changes.
API keys
Get a key and authenticate
The DBmuse REST API exposes the workspace metadata the DBmuse cloud stores: your projects, and the database connection entries inside them — name, type, host, port and database name. Connection credentials are not part of it: they never leave the client, so they are neither stored server-side nor returned by any endpoint.
Create an API key in the DBmuse dashboard, under API keys. Only an organization admin can create one. The secret is shown in full at creation and then hidden; revealing it again in the dashboard takes an admin re-entering their password, so store it somewhere safe. A key belongs to a single organization and a single project, so both are implied by the key and never have to be sent.
Authenticate every request with HTTP Basic auth carrying only the key secret, base64-encoded, in the Authorization header.
# The Authorization header is HTTP Basic auth carrying only the key secret,
# with no username and no colon.
Authorization: Basic $(printf %s YOUR_API_KEY_SECRET | base64)Every endpoint lives under https://api.dbmuse.com. Requests made with a key are rate limited per key; going over the limit returns 429.
Quick start
Your first three calls
Read your project, list the database connections in it, then register a new one.
# Read the project the key belongs to
curl https://api.dbmuse.com/api/projects \
-H "Authorization: Basic $(printf %s YOUR_API_KEY_SECRET | base64)"
# List the database connections of that project
curl https://api.dbmuse.com/api/databases \
-H "Authorization: Basic $(printf %s YOUR_API_KEY_SECRET | base64)"
# Register a new connection. Only metadata is stored — host, port, database
# name and type. Credentials stay on the client and are never sent here.
curl -X POST https://api.dbmuse.com/api/databases \
-H "Authorization: Basic $(printf %s YOUR_API_KEY_SECRET | base64)" \
-H "Content-Type: application/json" \
-d '{
"name": "staging cluster",
"type": "mongodb",
"host": "staging.example.com",
"port": 27017,
"database": "analytics"
}'Browse the full API reference — every endpoint with its parameters, request body, responses and required scope.
Scopes
Least privilege by default
Each key carries a list of scopes, so an integration that only needs to read your connection inventory never gets the ability to change it. New keys start read-only; widen them explicitly in the dashboard. A request whose key is missing the scope an endpoint requires is refused with 403.
- projects:readRead the project the key belongs to.
- projects:writeCreate, update and delete projects.
- databases:readList the project's database connections and read a single one.
- databases:writeCreate, update and delete database connections.
A key never sees another organization, and never another project than its own: anything outside its tenant answers 404 rather than 403, so an id belonging to someone else is indistinguishable from one that does not exist.
Webhooks
Signed webhooks
Add a webhook subscription to your project and DBmuse POSTs the events you picked to your server as they happen. Subscriptions are managed from the dashboard — the webhook subscription endpoints accept an operator access token, not an API key.
- project.createdA project was created.
- project.updatedA project was edited.
- project.deletedA project was deleted.
- database.createdA database connection was registered.
- database.updatedA database connection entry was edited.
- database.deletedA database connection was removed.
POST https://your-server.com/dbmuse-webhook
X-Dbmuse-Event: database.created
X-Dbmuse-Signature: t=1719000000,v1=<hmac-sha256 hex>
Content-Type: application/json
{
"event": "database.created",
"timestamp": 1719000000,
"data": { "...": "..." }
}Verify the signature
Every delivery carries an X-Dbmuse-Signature header of the form t=timestamp,v1=signature, where the signature is an HMAC-SHA256 of timestamp.body keyed by the subscription secret shown to you once when the subscription was created. The event name is repeated in X-Dbmuse-Event. Recompute the signature over the raw body and compare before trusting the payload.
import crypto from 'node:crypto'
// body must be the RAW request body, byte for byte
function verify(header, body, secret) {
const [t, v1] = (header || '').split(',').map(part => part.split('=')[1])
if (!t || !v1) return false
const expected = crypto
.createHmac('sha256', secret)
.update(`${t}.${body}`)
.digest('hex')
// timingSafeEqual throws on a length mismatch, so a malformed signature
// has to be rejected before the comparison rather than by it.
if (v1.length !== expected.length) return false
return crypto.timingSafeEqual(Buffer.from(v1), Buffer.from(expected))
}Delivery is one best-effort attempt with a five second timeout and no retries, so respond 2xx quickly and do the work asynchronously. An endpoint that fails twenty times in a row is disabled automatically and has to be re-enabled in the dashboard.
Start building