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:

Base URL
https://wehostdatabase.com

Paths 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.

Authenticated request
curl https://wehostdatabase.com/api/auth/get-session \
  -H "x-api-key: $WHD_API_KEY"
Never embed a key in client-side code, a public repo, or a browser bundle. Keep it in an environment variable or a secrets manager, and rotate it if it leaks.

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.

POST/api/auth/api-key/create
Request
curl https://wehostdatabase.com/api/auth/api-key/create \
  -X POST \
  -H "Content-Type: application/json" \
  --cookie "$SESSION_COOKIE" \
  -d '{
    "name": "ci-deploy",
    "expiresIn": null
  }'
Response · 200
{
  "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:

Example
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/health

Quickstart: 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.

1 · Discover valid engines, versions, packs & regions
curl https://wehostdatabase.com/api/v1/catalog
2 · Create a Postgres instance
curl 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", … }
3 · Poll until status is "running"
curl https://wehostdatabase.com/api/v1/orgs/$ORG/instances/$INSTANCE \
  -H "x-api-key: $WHD_API_KEY"
# → { "id": "inst_…", "status": "running", … }
4 · Fetch a ready-to-use connection string
curl https://wehostdatabase.com/api/v1/orgs/$ORG/instances/$INSTANCE/connection \
  -H "x-api-key: $WHD_API_KEY"
Connection response
{
  "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"
    }
  }
}
Connect over the pooled endpoint for web apps and serverless (thousands of short-lived clients share a small backend pool). Use direct for migrations, admin sessions, and anything needing session-level features. Both verify the server with 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

GET/api/v1/catalog

Valid engine, version, pack, and region ids for creating an instance. Unauthenticated.

Instances

GET/api/v1/orgs/:org/instances

List every instance in the organization.

POST/api/v1/orgs/:org/instances

Provision a new instance. Body: engine, version, packId, region, optional name.

GET/api/v1/orgs/:org/instances/:id

Fetch one instance, including its lifecycle status — poll this until it reads running.

DELETE/api/v1/orgs/:org/instances/:id

Deprovision an instance and free its capacity. Irreversible.

GET/api/v1/orgs/:org/instances/:id/connection

Credentials + ready-to-use direct and pooled connection URIs.

Databases

GET/api/v1/orgs/:org/instances/:id/databases

List the logical databases inside an instance.

POST/api/v1/orgs/:org/instances/:id/databases

Create a database. Body: name, optional owner role.

DELETE/api/v1/orgs/:org/instances/:id/databases/:databaseId

Drop a database by id.

Create a database inside an instance
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

GET/health

Liveness + dependency report. Returns 200 when healthy, 503 when a critical dependency is down. Unauthenticated, never cached.

Session & API keys

GET/api/auth/get-session

Returns the user the presented key resolves to. Handy as a token-validity probe.

POST/api/auth/api-key/create

Mint a new key. Returns the plaintext key once.

GET/api/auth/api-key/list

List your keys and their metadata (never the plaintext).

POST/api/auth/api-key/verify

Check whether a key is valid and see its metadata.

POST/api/auth/api-key/delete

Revoke a key by id. Takes effect immediately.

Revoke a key
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 · 401
{
  "error": {
    "code": "unauthorized",
    "message": "Invalid or missing API key."
  }
}
StatusMeaning
200 / 201Success.
400Malformed request — bad JSON or invalid field.
401Missing, invalid, or revoked API key.
402Billing required — enable usage billing before adding capacity.
403Your key isn't a member of that organization.
404No such organization, instance, or database.
409No host in the requested region has capacity right now.
429Rate limit exceeded — back off and retry.
503A 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).