# create_storage_backup

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

Takes an archive of a site's whole file storage, public and private files alike, so its files can be put back from it later.

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

It answers as soon as the archive is reserved, not when it is finished. The row comes back `pending`, and `list_storage_backups` reports it `ready` once the archive is done, or `failed` with the reason. The archive holds the storage as it is when its listing actually starts, which can be minutes after the call while other backups run, so it is not necessarily the files as they are right now.

Take it before deleting or moving a lot of stored files. The tool tells the client not to call `delete_storage_files`, `delete_storage_folder`, `clear_storage`, `move_storage_files` or `set_storage_visibility` on them until the row reads `ready`, because a file removed or moved before the archive reads it is simply left out of the zip. If the row reads `failed`, the client is told to tell you before going ahead.

It needs a paid workspace and spends one of the 10 manual backups a site gets in any 24 hours, the same allowance as **Backup** in the editor. 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. It is also refused while another backup of the same storage is still running (`A backup of this storage is already running!`), and while the storage is being restored (`Your storage is being restored from a backup. Take a new backup when the restore finishes!`).

A manual backup is taken even when nothing changed since the last archive. On a storage that holds no files at all the row still comes back `pending`, then reads `failed` with `There are no files in your storage to back up!`

With an access token, over MCP or the [HTTP API](https://modulify.ai/docs/api), the archive can be browsed with `browse_storage_backup`, read one text file at a time with `read_storage_backup_file` and restored with `restore_storage_backup`, which answers a plan on its first call and restores only on a second call carrying that plan's `confirm` value. Downloading it happens only in the editor, and the tool tells the client never to build a download link for it and never to restore it on its own initiative. See [Storage backups](https://modulify.ai/docs/editor/backups#backup).

## Request

Call it with a `POST` to `https://api.modulify.ai/v1/create_storage_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_storage_backup \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"projectId":"PROJECT_ID"}'
```

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

## Inputs

| Input | Type | Required | Description |
| --- | --- | --- | --- |
| `projectId` | string | Yes | The site to back up. |
| `name` | string | No | A short label saying what the archive is, for example `Before clearing the old uploads`. 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.