---
myst:
  html_meta:
    "description": "Available content types in a Plone site can be listed and queried by accessing the /@types endpoint on any context. Access requires an authenticated user."
    "property=og:description": "Available content types in a Plone site can be listed and queried by accessing the /@types endpoint on any context. Access requires an authenticated user."
    "property=og:title": "Types"
    "keywords": "Plone, plone.restapi, REST, API, Types"
---

(types)=

# Types

```{note}
These docs are generated by code tests, therefore you will see some `test` content types appear here.
```

Available content types in a Plone site can be listed and queried by accessing the `/@types` endpoint on any context.
Access requires an authenticated user.
The `addable` key specifies if the content type can be added to the current context.
The `layouts` key specifies the defined views:

```{eval-rst}
..  http:example:: curl httpie python-requests
    :request: ../../../src/plone/restapi/tests/http-examples/types.req
```

```{literalinclude} ../../../src/plone/restapi/tests/http-examples/types.resp
:language: http
```

The API consumer can create, read, update, and delete a content types schema.

| Verb    | URL              | Action                                             |
| ------- | ---------------- | -------------------------------------------------- |
| `POST`  | `/@types/{type}` | Add field/fieldset to content type schema          |
| `GET`   | `/@types/{type}` | Get the schema of a content type                   |
| `PATCH` | `/@types/{type}` | Update existing schema fields/fieldsets properties |
| `PUT`   | `/@types/{type}` | Replace content-type schema                        |

In addition to the above methods we can also do:

| Verb     | URL                              | Action                            |
| -------- | -------------------------------- | --------------------------------- |
| `GET`    | `/@type/{type}/{field/fieldset}` | Get field/fieldset properties     |
| `PATCH`  | `/@type/{type}/{field/fieldset}` | Update field/fieldset properties  |
| `DELETE` | `/@type/{type}/{field/fieldset}` | Remove field/fieldset from schema |

```{note}
Schema fields and fieldsets defined by [behaviors](https://5.docs.plone.org/external/plone.app.dexterity/docs/behaviors/index.html) are immutable and can NOT be changed via this RestAPI endpoint.
See {ref}`dexterity-types` control panel RestAPI endpoint for enabling and disabling behaviors.
```


## Add schema fieldset or field with `POST`

To create a new *fieldset*, send a `POST` request to the `/@types/Document` endpoint:

```{eval-rst}
..  http:example:: curl httpie python-requests
    :request: ../../../src/plone/restapi/tests/http-examples/types_document_post_fieldset.req
```

Response:

```{literalinclude} ../../../src/plone/restapi/tests/http-examples/types_document_post_fieldset.resp
:language: http
```

To create a new *field*, send a `POST` request to the `/@types/Document` endpoint:

```{eval-rst}
..  http:example:: curl httpie python-requests
    :request: ../../../src/plone/restapi/tests/http-examples/types_document_post_field.req
```

Response:

```{literalinclude} ../../../src/plone/restapi/tests/http-examples/types_document_post_field.resp
:language: http
```

For a complete list of available field `@types`, you can access `/@vocabularies/Fields` endpoint:

```{eval-rst}
..  http:example:: curl httpie python-requests
    :request: ../../../src/plone/restapi/tests/http-examples/vocabularies_get_fields.req
```

Response:

```{literalinclude} ../../../src/plone/restapi/tests/http-examples/vocabularies_get_fields.resp
:language: http
```


## Get the schema with `GET`

To get the schema of a content type, access the `/@types` endpoint with the name of the content type, for example, `plone/@types/Document`:

```{eval-rst}
..  http:example:: curl httpie python-requests
    :request: ../../../src/plone/restapi/tests/http-examples/types_document.req
```

```{literalinclude} ../../../src/plone/restapi/tests/http-examples/types_document.resp
:language: http
```

The content type schema uses the [JSON Schema](https://json-schema.org/) format.
The tagged values for the widgets are also exposed in the `properties` attribute of the schema.

For `Choice` fields, their vocabulary or source will be linked to in a `vocabulary` or `querysource` property (one or the other, never both):

- If a `querysource` property is included, that field is backed by an `IQuerysource`.
  In that case, the source's terms can't be enumerated.
  The terms need to be *queried* by issuing a request to the linked endpoint and including the user's search terms in the `?query=` parameter.
- If a `vocabulary` property is included, the field is backed by a vocabulary or another kind of iterable source.
  The terms can then be *enumerated* by issuing a request to the linked endpoint.

See {ref}`vocabularies` for details on these endpoints.

See {ref}`types-schema` for a detailed documentation about the available field types.

To get one schema **fieldset** properties, access `@types/Document/{fieldset}` endpoint:

```{eval-rst}
..  http:example:: curl httpie python-requests
    :request: ../../../src/plone/restapi/tests/http-examples/types_document_get_fieldset.req
```

```{literalinclude} ../../../src/plone/restapi/tests/http-examples/types_document_get_fieldset.resp
:language: http
```

To get one schema *field* properties, access `@types/Document/{field}` endpoint:

```{eval-rst}
..  http:example:: curl httpie python-requests
    :request: ../../../src/plone/restapi/tests/http-examples/types_document_get_field.req
```

```{literalinclude} ../../../src/plone/restapi/tests/http-examples/types_document_get_field.resp
:language: http
```


## Update schema with `PATCH`

To update content type schema defaults, we send a `PATCH` request to the server.
`PATCH` allows to provide just a subset of the resource, that is, the values you actually want to change.

To update one or more schema *field* properties:

```{eval-rst}
..  http:example:: curl httpie python-requests
    :request: ../../../src/plone/restapi/tests/http-examples/types_document_patch_properites.req
```

Response:

```{literalinclude} ../../../src/plone/restapi/tests/http-examples/types_document_patch_properites.resp
:language: http
```

To change one or more *fieldset* properties:

```{eval-rst}
..  http:example:: curl httpie python-requests
    :request: ../../../src/plone/restapi/tests/http-examples/types_document_patch_fieldsets.req
```

Response:

```{literalinclude} ../../../src/plone/restapi/tests/http-examples/types_document_patch_fieldsets.resp
:language: http
```

To update one *fieldset* settings, we can also send a `PATCH` request to `@types/Document/{fieldset}` endpoint:

```{eval-rst}
..  http:example:: curl httpie python-requests
    :request: ../../../src/plone/restapi/tests/http-examples/types_document_patch_fieldset.req
```

Response:

```{literalinclude} ../../../src/plone/restapi/tests/http-examples/types_document_patch_fieldset.resp
:language: http
```

To update one *field* settings, we can also send a `PATCH` request to `@types/Document/{field}` endpoint:

```{eval-rst}
..  http:example:: curl httpie python-requests
    :request: ../../../src/plone/restapi/tests/http-examples/types_document_patch_field.req
```

Response:

```{literalinclude} ../../../src/plone/restapi/tests/http-examples/types_document_patch_field.resp
:language: http
```


## Update schema with `PUT`

Use `PUT` when more changes are needed in one call, such as creating new fields or fieldsets, moving fields to a fieldset, removing multiple fields, and so on:

```{eval-rst}
..  http:example:: curl httpie python-requests
    :request: ../../../src/plone/restapi/tests/http-examples/types_document_put.req
```

```{literalinclude} ../../../src/plone/restapi/tests/http-examples/types_document_put.resp
:language: http
```


## Removing schema field/fieldset with `DELETE`

Delete an existing schema *field* by sending a `DELETE` request to the URL of an existing schema field:

```{eval-rst}
..  http:example:: curl httpie python-requests
    :request: ../../../src/plone/restapi/tests/http-examples/types_document_delete_field.req
```

Response:

```{literalinclude} ../../../src/plone/restapi/tests/http-examples/types_document_delete_field.resp
:language: http
```

Delete an existing schema *fieldset* by sending a `DELETE` request to the URL of an existing schema fieldset:

```{eval-rst}
..  http:example:: curl httpie python-requests
    :request: ../../../src/plone/restapi/tests/http-examples/types_document_delete_fieldset.req
```

Response:

```{literalinclude} ../../../src/plone/restapi/tests/http-examples/types_document_delete_fieldset.resp
:language: http
```
