Database
Previewcapability-gated
The database resource exposes the managed database behind an environment — its
metrics and schema, read queries, and exports — as a typed, scoped surface. It’s part
of the dynamic application layer: the depth a generic
PaaS won’t touch, delivered with scoped keys and async jobs.
endpoints
Section titled “endpoints”database metrics & schema
Section titled “database metrics & schema”GET …/{envID}/database
Returns size, table inventory, and engine metadata for the environment’s database — no row data, so this read is cheap and safe to poll.
{ "data": { "engine": "mysql", "version": "8.0", "size_bytes": 184320512, "tables": [ { "name": "wp_posts", "rows": 12840, "size_bytes": 5242880 }, { "name": "wp_options", "rows": 412, "size_bytes": 1048576 } ] }, "request_id": "req_01J9..."}read query
Section titled “read query”POST …/{envID}/database/query
Run a read-only query and get typed rows back. db:read rejects anything that
writes — INSERT, UPDATE, DELETE, DDL — so a read-scoped key can never mutate
data. Returns a job for large result sets.
| Parameter | Type | Required | Description |
|---|---|---|---|
query |
string | yes | A read-only SQL statement. Writes are rejected. |
params |
array | no | Bound parameters, in order, for placeholders in query. |
limit |
integer | no | Cap rows returned. A platform ceiling applies regardless. |
curl -X POST https://api.managed.dev/v1/sites/site_01J7.../environments/env_01J8.../database/query \ -H "Authorization: Bearer mfk_live_9aF2..." \ -H "Forge-Version: 2026-06-23" \ -H "Content-Type: application/json" \ -d '{ "query": "SELECT post_status, COUNT(*) AS n FROM wp_posts WHERE post_type = ? GROUP BY post_status", "params": ["post"] }'const result = await mf.database.query( { siteId: "site_01J7...", envId: "env_01J8..." }, { query: "SELECT post_status, COUNT(*) AS n FROM wp_posts WHERE post_type = ? GROUP BY post_status", params: ["post"], },);mf db query --env env_01J8... \ "SELECT post_status, COUNT(*) AS n FROM wp_posts WHERE post_type = 'post' GROUP BY post_status"{ "data": { "columns": ["post_status", "n"], "rows": [ { "post_status": "publish", "n": 240 }, { "post_status": "draft", "n": 18 } ], "row_count": 2 }, "request_id": "req_01J9..."}export the database
Section titled “export the database”POST …/{envID}/database/export
Produce a downloadable dump of the environment’s database. Returns 202 Accepted
with a job; when it completes, the job’s result
carries a short-lived signed download URL.
| Parameter | Type | Required | Description |
|---|---|---|---|
tables |
array | no | Restrict the export to named tables. Omit for the whole database. |
compress |
boolean | no | Gzip the dump. Defaults to true. |
-
Request the export.
Export the whole database, compressed curl -X POST https://api.managed.dev/v1/sites/site_01J7.../environments/env_01J8.../database/export \-H "Authorization: Bearer mfk_live_9aF2..." \-H "Forge-Version: 2026-06-23" \-H "Idempotency-Key: c7e0-18aa-9d31" \-H "Content-Type: application/json" \-d '{ "compress": true }'202 response HTTP/1.1 202 AcceptedLocation: /v1/jobs/job_01J9...{"data": { "id": "job_01J9...", "type": "database.export", "status": "queued","created_at": "2026-06-23T18:22:40.118Z","resource": { "type": "database", "site_id": "site_01J7...", "env_id": "env_01J8..." } },"request_id": "req_01J9..."} -
Wait for the job, then read its
resultfor the signed URL. See async jobs.Completed job result { "download_url": "https://files.managed.dev/exports/...?sig=...","expires_at": "2026-06-23T19:22:40Z", "size_bytes": 41943040 }
destructive writes
Section titled “destructive writes”Write access lives behind db:write and is treated with care. A write query or a
schema migration is dry-run by default: send "confirm": false (the default) to
get back the rows or statements that would change, then resend with
"confirm": true to apply. Pair any write with a snapshot
so a mistake is one restore away.