API Reference
WeHostDatabase API
A JSON-over-HTTPS API for scripting your account. Create an API key, send it on every request, and drive the same operations the dashboard uses — from CI pipelines, cron jobs, or your own tooling.
Introduction
The API speaks JSON over HTTPS. Every request must be made over TLS; plain-HTTP requests are refused. Request and response bodies are application/json unless noted otherwise. Timestamps are ISO 8601 (UTC).
Authentication is handled with long-lived API keys scoped to your account. A key carries the same permissions as the user that created it, so treat it like a password — anyone holding it can act as you.
Base URL
All endpoints are relative to a single origin:
https://wehostdatabase.comPaths in this reference are shown relative to that origin — e.g. GET /health means https://wehostdatabase.com/health.
Authentication
Send your key in the x-api-key header on every request. Requests without a valid key that hit a protected endpoint return 401 Unauthorized.
curl https://wehostdatabase.com/api/auth/get-session \
-H "x-api-key: $WHD_API_KEY"Create an API key
Keys are minted from an authenticated session — so you create your first key while signed in to the dashboard (the browser sends your session cookie for you). The response includes the full key exactly once; store it immediately, because it is never shown again.
/api/auth/api-key/createcurl https://wehostdatabase.com/api/auth/api-key/create \
-X POST \
-H "Content-Type: application/json" \
--cookie "$SESSION_COOKIE" \
-d '{
"name": "ci-deploy",
"expiresIn": null
}'{
"id": "key_a1b2c3d4",
"name": "ci-deploy",
"key": "whd_7f3c9e...c0ffee",
"createdAt": "2026-07-21T09:30:00.000Z"
}Set expiresIn to a number of seconds to auto-expire the key, or null for a non-expiring key.
Using your key
Once you hold a key, attach it as x-api-key and call any endpoint. Here is the full round-trip — check who the key belongs to, then read service health:
export WHD_API_KEY="whd_7f3c9e...c0ffee"
# Who am I?
curl https://wehostdatabase.com/api/auth/get-session \
-H "x-api-key: $WHD_API_KEY"
# Is the platform healthy?
curl https://wehostdatabase.com/healthQuickstart: provision a database
The provisioning API lives under /api/v1 and is scoped to an organization by its slug — the same slug you see in the dashboard URL (/{org}/instances). The flow is: pick a pack, create an instance, poll until it's running, then pull its connection string.
curl https://wehostdatabase.com/api/v1/catalogcurl https://wehostdatabase.com/api/v1/orgs/$ORG/instances \
-X POST \
-H "Content-Type: application/json" \
-H "x-api-key: $WHD_API_KEY" \
-d '{
"name": "prod-db",
"engine": "postgres",
"version": "17",
"packId": "starter",
"region": "us-east"
}'
# → 201 { "id": "inst_…", "status": "provisioning", … }curl https://wehostdatabase.com/api/v1/orgs/$ORG/instances/$INSTANCE \
-H "x-api-key: $WHD_API_KEY"
# → { "id": "inst_…", "status": "running", … }curl https://wehostdatabase.com/api/v1/orgs/$ORG/instances/$INSTANCE/connection \
-H "x-api-key: $WHD_API_KEY"{
"host": "inst-….pg.us-east.wehostdatabase.com",
"user": "postgres",
"password": "••••••••",
"engine": "postgres",
"defaultDatabase": "postgres",
"sslMode": "verify-full",
"endpoints": {
"direct": {
"port": 24187,
"uri": "postgresql://postgres:…@inst-….wehostdatabase.com:24187/postgres?sslmode=verify-full"
},
"pooled": {
"port": 24188,
"uri": "postgresql://postgres:…@inst-….wehostdatabase.com:24188/postgres?sslmode=verify-full"
}
}
}sslmode=verify-full against our private CA — download the CA bundle from the dashboard's Connect tab and pass it as sslrootcert.Endpoints
The provisioning surface lives under /api/v1; account and key-management routes live under /api/auth. All /api/v1/orgs/* routes require the x-api-key header and are scoped to that org.
Catalog
/api/v1/catalogValid engine, version, pack, and region ids for creating an instance. Unauthenticated.
Instances
/api/v1/orgs/:org/instancesList every instance in the organization.
/api/v1/orgs/:org/instancesProvision a new instance. Body: engine, version, packId, region, optional name.
/api/v1/orgs/:org/instances/:idFetch one instance, including its lifecycle status — poll this until it reads running.
/api/v1/orgs/:org/instances/:idDeprovision an instance and free its capacity. Irreversible.
/api/v1/orgs/:org/instances/:id/connectionCredentials + ready-to-use direct and pooled connection URIs.
Databases
/api/v1/orgs/:org/instances/:id/databasesList the logical databases inside an instance.
/api/v1/orgs/:org/instances/:id/databasesCreate a database. Body: name, optional owner role.
/api/v1/orgs/:org/instances/:id/databases/:databaseIdDrop a database by id.
curl https://wehostdatabase.com/api/v1/orgs/$ORG/instances/$INSTANCE/databases \
-X POST \
-H "Content-Type: application/json" \
-H "x-api-key: $WHD_API_KEY" \
-d '{ "name": "analytics" }'
# → 201 { "id": "db_…", "name": "analytics", "status": "creating" }Service
/healthLiveness + dependency report. Returns 200 when healthy, 503 when a critical dependency is down. Unauthenticated, never cached.
Session & API keys
/api/auth/get-sessionReturns the user the presented key resolves to. Handy as a token-validity probe.
/api/auth/api-key/createMint a new key. Returns the plaintext key once.
/api/auth/api-key/listList your keys and their metadata (never the plaintext).
/api/auth/api-key/verifyCheck whether a key is valid and see its metadata.
/api/auth/api-key/deleteRevoke a key by id. Takes effect immediately.
curl https://wehostdatabase.com/api/auth/api-key/delete \
-X POST \
-H "Content-Type: application/json" \
-H "x-api-key: $WHD_API_KEY" \
-d '{ "keyId": "key_a1b2c3d4" }'Errors
The API uses conventional HTTP status codes. 2xx means success, 4xx means the request was rejected (and retrying unchanged won't help), and 5xx means something failed on our side. Error responses carry a JSON body:
{
"error": {
"code": "unauthorized",
"message": "Invalid or missing API key."
}
}| Status | Meaning |
|---|---|
200 / 201 | Success. |
400 | Malformed request — bad JSON or invalid field. |
401 | Missing, invalid, or revoked API key. |
402 | Billing required — enable usage billing before adding capacity. |
403 | Your key isn't a member of that organization. |
404 | No such organization, instance, or database. |
409 | No host in the requested region has capacity right now. |
429 | Rate limit exceeded — back off and retry. |
503 | A critical dependency is unavailable. |
Rate limits
Each API key is limited to 120 requests per minute. Over that you receive 429 Too Many Requests; wait for the window to reset and retry with exponential backoff. Build clients to treat 429 as retryable rather than fatal, and space out status polling (every few seconds is plenty).