# Management API (/docs/api/management)

The management API keeps a [content model file](/docs/guides/content-model#the-model-file) in step with one space environment. It is what [the CLI](/docs/sdk/cli) calls; use it directly from other tooling.

Every request takes `Authorization: Bearer cms_m_…`, a management token of the environment (Settings → API tokens, kind Management). The token acts as the person who created it, with their current [role](/docs/guides/roles): changing the model needs an admin or developer.

| Request                                                   | Does                                                                                                    |
| --------------------------------------------------------- | ------------------------------------------------------------------------------------------------------- |
| `GET /api/management/v1/model`                            | The environment's model file                                                                            |
| `POST /api/management/v1/model/plan` `{ model, prune? }`  | The plan: `{ changes, issues }`                                                                         |
| `POST /api/management/v1/model/apply` `{ model, prune? }` | Applies it, all or nothing, answering the plan                                                          |
| `GET /api/management/v1/improve`                          | `{ enabled, sources }`: the Improve tests and flags the [improve block](/docs/guides/ab-tests) can name |

- `changes` lists every content type the file creates, updates or deletes, with the entries that would lose values when a field is removed.
- `issues` lists what stands in the way (a field whose type changes, a type in use changing kind, deleting a type others use); `apply` refuses while there are any.
- `prune: true` also deletes content types the file leaves out. Without it, a file can describe part of a model.
- A type's `groups`, `accent` and `code` ([how the dashboard shows it](/docs/guides/content-model#groups-accent-and-code)) are in every export. A file that leaves them out keeps what the environment has, so a file from before them applies without undoing them.

Errors are `{ error, issues? }` with `400`, `401` (missing, invalid or revoked token) or `403` (the role doesn't allow it, or Content is turned off). Applying sends `model.changed` [webhooks](/docs/guides/webhooks).

Full request and response shapes are in [`/openapi.json`](https://content.obelism.studio/openapi.json) (tag Management).

## Content with a management token [#content-with-a-management-token]

A management token can also have the **content** scope (Settings → API tokens → What it may do, or `scopes: ["content"]` in the agent API). With it, the token is a bearer token for the [agent API's](/docs/api/agents) content routes in its own space and environment: entries (including [bulk actions](/docs/guides/publishing#several-entries-at-once)), assets, the trash and redirects, and reading content types. Use it for migrations, imports and scheduled jobs that shouldn't depend on someone's session.

```sh
curl -X POST "https://content.obelism.studio/api/agent/organizations/$ORG/spaces/$SPACE/develop/entries" \
  -H "Authorization: Bearer $CONTENT_MANAGEMENT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "contentType": "post", "name": "Imported post", "slug": "imported-post", "content": { "title": { "en": "Imported" } } }'
```

The token still acts as the person who created it, with their current role: if they become a reader or leave the organization, it stops writing. Everything else (tokens, webhooks, settings, the model, promotion) refuses it with [`token_not_allowed`](/docs/api/errors#token_not_allowed), and so does any other space or environment. Existing management tokens have only the model scope.
