# The admin API of the Total.js CMS: manage a site from code, backup and restore

> The JSON API behind the CMS admin at /admin/: the call format, the actions of each plugin and their permissions, uploading files, and the three routes for backup, restore and clear, including what clear really does.

Framework: cms
Product: CMS (cms@8071e48)
Language: en
Content-SHA256: d0108c50f8c67f006e4deadc87b0c0812812b447c52bc468e4579ab8c2d503b5
Snapshot: c0700e321579725c5cf4f5ace1ad7d2866d1b4f93c24a63c0b41b6b7998e976c
Sources: 
Review: not-recorded

Everything the admin interface does goes through one endpoint: `POST /admin/` with the body `{ "schema": "<name>", "data": { ... } }` (the Total.js API routes, see [API routes](/en/total5/api-routes/)). The address comes from the line `$api : /admin/` of the file `config`. Authenticate with the session cookie (`POST /admin/` with `schema: "login"` and the `login` and `password`), with the header `x-token` or through OpenPlatform ([install and first start](/en/cms/install-and-first-start/)).

## The actions

| Plugin | Calls (`schema`) | Permission |
|---|---|---|
| Account | `login`, `logout`, `admin_read`, `admin_save` (name, login, password), `account` | the session |
| Pages | `pages_list`, `pages_read`, `pages_save`, `pages_clone`, `pages_remove`, `pages_links`, `pages_html` (reads the HTML), `pages_save_html` (`id`, `html`, up to 5 MB), `pages_copy` (`from`, `to`) | `pages` |
| Layouts | `layouts_list`, `layouts_read`, `layouts_save`, `layouts_clone`, `layouts_remove`, `layouts_html`, `layouts_save_html`, `layouts_import` | `layouts` |
| Widgets | `widgets_list`, `widgets_read`, `widgets_save`, `widgets_remove`, `widgets_detail` | `widgets` |
| Navigation | `nav_list`, `nav_read`, `nav_save`, `nav_remove`, `nav_editor` | `navigation` |
| Redirects | `redirects_list`, `redirects_read`, `redirects_save` (`url`, `target`, `permanent`), `redirects_remove` | `redirects` |
| Variables | `variables_read`, `variables_save` (`vars`) | `variables` |
| Posts | `posts`, `posts_read`, `posts_create`, `posts_update`, `posts_remove`, `posts_clear`, `posts_categories` | `posts` |
| Files | `files_list`, `files_rename`, `files_clear`, `files_remove`, and the uploads below | `files` |
| Settings | `settings_read`, `settings_save`, `settings_test` (tries the SMTP settings), `chatgpt` | `settings` |
| Dashboard | `dashboard_online`, `dashboard_referers`, `dashboard_browsers`, `dashboard_pages`, `dashboard_stats` | none |

The permission `admin` (and every user with the flag `sa`, including the *Bot* of the token) is allowed in all of them. A call without permission is answered with an error, and `login` is the only call that does not need a session.

Create a page and its content:

```json
{ "schema": "pages_save", "data": { "name": "About", "layoutid": "<layout id>", "url": "/about/", "title": "About us" } }
{ "schema": "pages_save_html", "data": { "id": "<page id>", "html": "<h1>About us</h1>" } }
```

`pages_save` answers `{ "success": true }`; read the id with `pages_list`. For a layout, `layouts_save` answers the id of the layout in `value`. When a field is missing from an update, the field is cleared (a `title` that you do not send is saved empty), so send the whole record.

## Uploading files

`POST /admin/upload/` takes a multipart upload (up to 10 MB) and `POST /admin/upload/base64/` a JSON body with a data URI (png, jpeg or gif). Both answer a list of `{ id, name, type, ext, size, url }` where `url` is `/download/<id>.<ext>`.

## Backup, restore and clear

Three routes of `controllers/api.js` work on the whole site and need the permission `admin`:

| Route | What it does |
|---|---|
| `GET /admin/backup/` | downloads the whole file storage (metadata, HTML of pages and layouts, files and posts) as one text file named after the site and the date |
| `POST /admin/restore/` | uploads such a file (up to 100 MB) and loads it. |
| `GET /admin/clear/` | **deletes the content of the site.** It drops the file storage and loads it again, so pages, layouts, widgets and the rest are removed |

Make a backup before you try any of these, never open `/admin/clear/` in a browser out of curiosity, and keep the token private: with it, a single `GET` empties the site.
