# create_database_backup

Source: https://modulify.ai/docs/api/backups/create-database-backup

Takes an archive of a site's database, a plain SQL dump of every table and row, so the data can be recovered by hand later.

- Title: Take a database backup
- Scope: `sites:write`
- Access: Makes changes
- Endpoint: `POST /v1/create_database_backup`

Every table and row goes into one `database.sql` inside the zip that [What is inside a database backup](https://modulify.ai/docs/editor/backups#what-is-inside-a-database-backup) describes. It answers as soon as the archive is reserved, not when it is finished: the row comes back `pending`, and `list_database_backups` reports it `ready` once the export is done, or `failed` with the reason. The archive holds the database as it is when its export actually starts, which can be minutes after the call while other backups run.

Take it before a destructive migration, a bulk update, emptying a collection or dropping the whole database. The tool tells the client not to run that statement, `clear_collection` or `clear_site_database` until the row reads `ready`, and to tell you before going ahead if it reads `failed`.

It needs a paid workspace and spends one of the 10 manual database backups a site gets in any 24 hours, counted apart from storage backups. A backup that fails does not spend one, but deleting one does not hand its slot back, so the allowance only refills as each of those backups passes a day old. A manual backup is taken even when nothing changed since the last archive.

It is refused on a site that is not on the newer database (`Database backups are only available for sites on the newer database!`), on a site with no database yet (`This site does not have a database to back up yet!`) and while another backup of the same database is still running (`A backup of this database is already running!`), so read `eligibility` from `list_database_backups` first. On a database with no tables the row still comes back `pending` and then reads `failed` with `Your database has no tables to back up!`, and a database holding a full text search table fails outright with `Your database has a full text search table, which cannot be backed up!`

The database stops answering for a moment while the export runs, so a statement that fails as unavailable just then is worth trying once more. The tool tells the client never to call it a restore point: a database backup cannot be restored, and it cannot be downloaded through MCP at all, only in the editor. See [Back up your database now](https://modulify.ai/docs/editor/backups#back-up-your-database-now).

## Request

Call it with a `POST` to `https://api.modulify.ai/v1/create_database_backup`, sending the inputs below as a JSON object. The token needs the `sites:write` scope.

It makes changes, so send an [Idempotency-Key](https://modulify.ai/docs/api/idempotency) header whenever you might retry it. A retry with the same key gets the first answer back instead of running again.

```bash
curl -X POST https://api.modulify.ai/v1/create_database_backup \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"projectId":"PROJECT_ID"}'
```

Over MCP, the same method is the [create_database_backup tool](https://modulify.ai/docs/mcp/backups/create-database-backup).

## Inputs

| Input | Type | Required | Description |
| --- | --- | --- | --- |
| `projectId` | string | Yes | The site whose database should be backed up. |
| `name` | string | No | A short label saying what the archive is, for example `Before the orders migration`. When given, it must be 2 to 84 characters. |

## Response

Every call answers with the [JSON envelope](https://modulify.ai/docs/api/requests-and-responses#the-response) of `success`, `message`, `data`, `code` and `version`. `data` holds the result described above, and on a method that returns a total, `count` carries it. The [response headers](https://modulify.ai/docs/api/requests-and-responses#headers-on-every-method-call) carry the call's `X-Request-Id` and what is left of your per-minute budget in `X-RateLimit-Limit`, `X-RateLimit-Remaining` and `X-RateLimit-Reset`. [Errors](https://modulify.ai/docs/api/errors) explains every status code a call can answer with.