Flex Objects
Endpoints for managing Flex Object directories and their records: listing directories and blueprints, full CRUD on objects, YAML export, and per-object media (files stored alongside the object in its own folder).
Endpoints for managing Flex Object directories and their records: listing directories and blueprints, full CRUD on objects, YAML export, and per-object media (files stored alongside the object in its own folder).
Get Flex Config
/flex-objects/config
{"data": {"enabled": true, "built_in_css": true, "admin_list": {"per_page": 15}}}
Response Codes
Lightweight configuration endpoint. The list of directories is returned separately by GET /flex-objects so callers that only need config stay small.
List Directories
/flex-objects
{"data": [{"type": "contacts", "title": "Contacts", "icon": "fa-address-book", "list": {"fields": {"name": {}, "email": {}}}, "field_types": {"name": "text", "email": "email"}}]}
Response Codes
Each entry's type is the Flex directory key you pass as {type} to the object endpoints below. Directories the user lacks list permission on are omitted from the result.
List Blueprints
/flex-objects/blueprints
{"data": [{"url": "blueprints://flex-objects/contacts.yaml", "legacy_url": null, "type": "contacts", "title": "Contacts", "description": "Address book"}]}
Response Codes
legacy_url carries the pre-existing blueprint alias (when one exists) so saved settings that still reference the old form can be matched.
List Objects
/flex-objects/{type}
Parameters
| Name | Type | Description |
|---|---|---|
| type required | string | The Flex directory type (e.g. `contacts`). |
| page optional | integer | Page number for pagination (default 1). |
| per_page optional | integer | Number of results per page (default 20, max 1000). |
| search optional | string | Search term applied across the directory's searchable fields. |
| sort optional | string | Field to sort by. |
| order optional | string | Sort direction: `asc` (default) or `desc`. |
{"data": [{"key": "ada", "name": "Ada Lovelace", "email": "[email protected]"}], "meta": {"total": 1, "page": 1, "per_page": 20}}
Response Codes
The key on each item is the object identifier you pass as {key} to the single-object endpoints.
Get Object
/flex-objects/{type}/{key}
Parameters
| Name | Type | Description |
|---|---|---|
| type required | string | The Flex directory type (e.g. `contacts`). |
| key required | string | The object key. |
{"data": {"key": "ada", "name": "Ada Lovelace", "email": "[email protected]"}}
Response Codes
Keep the returned ETag and send it back as an If-Match header when updating, so a concurrent change is detected instead of silently overwritten.
Create Object
/flex-objects/{type}
Parameters
| Name | Type | Description |
|---|---|---|
| type required | string | The Flex directory type (e.g. `contacts`). |
{"name": "Grace Hopper", "email": "[email protected]"}
{"data": {"key": "grace-hopper", "name": "Grace Hopper", "email": "[email protected]"}}
Response Codes
Post to the collection address (no key segment). To attach files to the object afterwards, use the Upload Object Media endpoint below with the key returned here.
Update Object
/flex-objects/{type}/{key}
Parameters
| Name | Type | Description |
|---|---|---|
| type required | string | The Flex directory type (e.g. `contacts`). |
| key required | string | The object key. |
{"email": "[email protected]"}
{"data": {"key": "grace-hopper", "name": "Grace Hopper", "email": "[email protected]"}}
Response Codes
This is a partial update: fields you omit are left untouched. Use PATCH, not POST (posting to an object URL is not allowed).
Delete Object
/flex-objects/{type}/{key}
Parameters
| Name | Type | Description |
|---|---|---|
| type required | string | The Flex directory type (e.g. `contacts`). |
| key required | string | The object key. |
Response Codes
Returns no content on success.
Export Directory
/flex-objects/{type}/export
Parameters
| Name | Type | Description |
|---|---|---|
| type required | string | The Flex directory type (e.g. `contacts`). |
Response Codes
The response is application/x-yaml with a filename like contacts-YYYY-MM-DD.yaml, not the standard JSON envelope.
List Object Media
/flex-objects/{type}/{key}/media
Parameters
| Name | Type | Description |
|---|---|---|
| type required | string | The Flex directory type (e.g. `contacts`). |
| key required | string | The object key. |
{"data": [{"filename": "avatar.png", "type": "image/png", "size": 20480, "url": "/user/data/flex-objects/contacts/ada/avatar.png"}]}
Response Codes
Object media requires folder-based storage (one folder per object, e.g. user-data://flex-objects/contacts/{id}). Directories that keep all records in a single shared file have nowhere to store per-object files, and the endpoint returns 422.
Upload Object Media
/flex-objects/{type}/{key}/media
Parameters
| Name | Type | Description |
|---|---|---|
| type required | string | The Flex directory type (e.g. `contacts`). |
| key required | string | The object key. |
| file required | file | File(s) to upload (multipart/form-data). Nested fields like `file[]` are supported. |
{"data": [{"filename": "avatar.png", "type": "image/png", "size": 20480}]}
Response Codes
Send the file as a multipart/form-data request (set Content-Type: multipart/form-data), not JSON. Uploads are validated against Grav''s dangerous-extensions list and a 64 MB size cap. Requires folder-based storage for the directory (one folder per object); directories that use single-file storage return 422.
Delete Object Media
/flex-objects/{type}/{key}/media/{filename}
Parameters
| Name | Type | Description |
|---|---|---|
| type required | string | The Flex directory type (e.g. `contacts`). |
| key required | string | The object key. |
| filename required | string | The media filename to delete. |
Response Codes
Returns no content on success.