GuidesDatabasesEverywhere6 min read

DatabasesEverywhere API integration

The panel owns customers and customer-facing records; DatabasesEverywhere owns database containers. Integrate them over the authenticated JSON API and store the mapping between each panel record and daemon instance_id.

Authentication

Every HTTP request needs the node token from config.yml:

text
Authorization: Bearer <token>

The node token has the * scope. Do not put it in a query string; query-string node tokens return 401. The only query credential is the short-lived JWT inside a daemon-generated temporary download URL.

The request Host must match remote, a concrete api.host, or api.trusted_hosts. Browser Origin is checked independently. The default authenticated limit is 600 requests per minute per credential and transport-peer IP; IPv6 peers share a /64.

Request bodies are capped by security.api_body_limit_bytes. The listener also applies bounded connection, in-flight request, header, TLS handshake, and body inactivity limits.

Error format

Validation and authorization failures use one predictable shape:

json
{ "error": "what went wrong", "code": "bad_request" }

Internal failures return internal server error, internal_error, and an opaque error_id also present in X-Error-Id. Use that identifier to find the private cause in daemon logs.

  • 400 means validation failed.
  • 401 means missing or incorrect credentials, disallowed host or origin, or a node token in the query string.
  • 403 means the credential lacks the required scope.
  • 404 means an instance, job, artifact, or backup does not exist.
  • 409 means a runtime conflict.
  • 429 means the caller exceeded admission or rate limits.
  • 501 means an endpoint is not implemented.
  • 500 means a private daemon-side failure.

Contract version and scopes

Call GET /api/system when registering a node and compare api_version with the contract supported by your panel. The daemon binary version may change independently from the API contract.

Contract 0.7.0 includes local, S3, and Kopia backup storage plus bounded backup catalog browsing. Earlier 0.6.0 added typed credential-based remote imports, 0.5.0 exposed the rate-limit contract, and 0.4.0 established 500 ms monitoring snapshots for network-isolated containers.

Available scoped permissions include:

  • system:read, instances:read, and instances:write.
  • resources:read, resources:admin, logs:read, and metrics:read.
  • artifacts:read, artifacts:write, backups:read, backups:write, and backups:admin.
  • import-export:read, import-export:write, and recovery:admin.
  • images:admin, ws-tokens:write, monitor:read, and config:admin.

Scoped tokens are primarily used for browser-facing WebSockets. The node token retains *.

Instance model

An instance is one isolated database container. A typical response contains identity, protocol, status, public routing, runtime metadata, database ownership, resource limits, image state, detected database version, and timestamps:

json
{
  "schema_version": 1,
  "instance_id": "cust-42-db",
  "protocol": "postgres",
  "status": "running",
  "public": { "host": "db.example.com", "port": 5432 },
  "runtime": {
    "kind": "docker",
    "container_name": "dbev-cust-42-db",
    "network_mode": "none"
  },
  "database": { "name": "app_db", "username": "app_user" },
  "limits": {
    "cpu_cores": 1.0,
    "memory_mib": 2048,
    "disk_mib": 10240,
    "disk_enforced": true,
    "disk_enforcement_method": "fuse_quota"
  },
  "image": {
    "current": "postgres:18.4",
    "configured": "postgres:18.4",
    "update_available": false
  },
  "database_version": { "current": "18.4", "error": null }
}

Statuses are creating, booting, running, stopped, failed, quarantined, and deleting. Protocols are postgres, mariadb, mysql, redis, mongodb, clickhouse, and qdrant.

Instance endpoints

  • GET /api/instances lists instances with live classified status.
  • POST /api/instances accepts creation and returns 202 immediately.
  • GET /api/instances/{id} fetches one instance.
  • DELETE /api/instances/{id}?confirm=true&reason=... irreversibly deletes the instance and all managed data after explicit confirmation and an audit reason.
  • GET /api/instances/{id}/status returns status and available creation progress.
  • POST /api/instances/{id}/power accepts start, stop, restart, or kill.
  • POST /api/instances/{id}/reconcile resynchronizes stored status with the runtime.
  • PATCH /api/instances/{id}/limits updates all three resource limits.
  • PATCH /api/instances/{id}/image changes the configured image and recreates the container.
  • GET /api/instances/{id}/resources reports current usage.
  • GET /api/instances/{id}/logs?tail=200 returns up to 2,000 log lines.

Power calls are idempotent where practical: starting a running instance or stopping a stopped instance is a successful no-op.

Create an instance

json
POST /api/instances
{
  "instance_id": "cust-42-db",
  "protocol": "postgres",
  "database": "app_db",
  "username": "app_user",
  "password": "generated-by-panel",
  "public_host": "db.example.com",
  "public_port": 5432,
  "project_id": "optional-grouping-id",
  "limits": {
    "cpu_cores": 1.0,
    "memory_mib": 2048,
    "disk_mib": 10240
  }
}

Accepted response:

json
{
  "instance_id": "cust-42-db",
  "status": "creating",
  "status_url": "/api/instances/cust-42-db/status"
}

Poll status_url or watch the monitoring WebSocket. Failed creation remains observable with its final stage and message.

Mirror these rules in the panel for friendly validation:

  • Database and username are 1 to 63 characters, start with an ASCII letter, and then use letters, digits, _, or -.
  • Reserved names such as postgres, mysql, admin, root, default, dbe_admin, and dbe_health are rejected.
  • Password and public host cannot be empty.
  • CPU is between 0.01 and 1024 cores.
  • Memory is between 1 MiB and 1 TiB.
  • Disk must be greater than zero.
  • MongoDB and ClickHouse need at least 1024 MiB of both memory and disk.

Creation admission is bounded to 64 accepted background tasks. Operations on one instance remain serialized by its lock.

Power and limits

Use the unified power endpoint:

json
POST /api/instances/cust-42-db/power
{ "action": "restart" }

All resource fields are required when changing limits:

json
PATCH /api/instances/cust-42-db/limits
{ "cpu_cores": 2.0, "memory_mib": 4096, "disk_mib": 20480 }

Protocol-specific floors still apply. Capacity increases can be rejected when they would cross node allocation or host-availability reserves.

Image updates

json
PATCH /api/instances/cust-42-db/image
{ "image": "postgres:18.4", "password": "the-instance-password" }

The image must use a non-latest tag or digest and appear in the protocol allow-list. Password is required for every protocol except Redis.

Major updates for PostgreSQL, MariaDB, MySQL, MongoDB, and ClickHouse require explicit authorization:

json
PATCH /api/instances/cust-42-db/image
{
  "image": "mongo:8.3.4",
  "password": "the-instance-password",
  "major_upgrade": true
}

The daemon exports the old database, preserves its volume, creates a fresh target-version volume, imports the data, validates the replacement, and retains rollback material. Redis and Qdrant major updates are rejected because their physical backup formats are version-specific.

Warm a node before placement with:

json
POST /api/admin/images/pull
{ "protocol": "postgres", "image": "postgres:18.4" }

This endpoint requires images:admin. Omit image to pull the configured default.

Resource reports

GET /api/instances/{id}/resources returns configured limits and current CPU, memory, disk, and gateway network counters. CPU and memory can be null when the container is stopped or runtime stats are temporarily unavailable.

Network counters are measured at the authenticated gateway-to-Unix-socket boundary. RX is traffic delivered to the database and TX is traffic returned by it; counters restart at zero when the daemon boots.

Use GET /api/admin/resources/summary as the scheduler view. It combines:

  • Physical node capacity and configured allocation limits.
  • Reserved memory and disk.
  • Allocated resources, including stopped and failed instances.
  • Actual host and managed-container pressure.
  • Instance counts by lifecycle status.

Poll every 10 to 30 seconds for placement decisions. Treat allocation pressure as the primary scheduling signal and current host pressure as a secondary signal. The panel must still handle a final capacity rejection because availability can change between polling and creation.